转:spring中InitailizingBean接口的简单理解
转自:https://www.cnblogs.com/wxgblogs/p/6849782.html
spring中InitializingBean接口使用理解
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法。
测试程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service; public class InitBean implements InitializingBean{ public void afterPropertiesSet() throws Exception { System. out .println( "启动时自动执行 afterPropertiesSet..." ); } public void init(){ System. out .println( "init method..." ); } } |
配置文件如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?xml version= "1.0" encoding= "UTF-8" ?> <beans xmlns= "http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:context= "http://www.springframework.org/schema/context" xmlns:dubbo= "http://code.alibabatech.com/schema/dubbo" xmlns:mvc= "http://www.springframework.org/schema/mvc" xmlns:aop= "http://www.springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xsi:schemaLocation= "http: //www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http: //www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http: //www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http: //www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http: //www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http: //code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd" default -lazy-init= "true" > <bean id= "initBean" class = "com.netease.nsip.spring.InitBean" init-method= "init" > </bean> </beans> |
Main主程序如下:
1
2
3
4
5
6
7
8
9
10
|
import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext( "classpath:/applicationContext-core.xml" ); context.getBean( "initBean" ); } } |
运行Main程序,打印如下结果:
1
2
|
启动时自动执行 afterPropertiesSet... init method... |
这说明在spring初始化bean的时候,如果bean实现了InitializingBean接口,会自动调用afterPropertiesSet方法。
问题:实现InitializingBean接口与在配置文件中指定init-method有什么不同?由结果可看出,在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,并且同时在配置文件中指定了init-method,系统则是先调用afterPropertiesSet方法,然后在调用init-method中指定的方法。这方式在spring中是怎么实现的?通过查看spring的加载bean的源码类(AbstractAutowireCapableBeanFactory)可看出其中奥妙AbstractAutowireCapableBeanFactory类中的invokeInitMethods讲解的非常清楚,源码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { //判断该bean是否实现了实现了InitializingBean接口,如果实现了InitializingBean接口,则只掉调用bean的afterPropertiesSet方法 boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod( "afterPropertiesSet" ))) { if (logger.isDebugEnabled()) { logger.debug( "Invoking afterPropertiesSet() on bean with name '" + beanName + "'" ); } if (System.getSecurityManager() != null ) { try { AccessController.doPrivileged( new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { //直接调用afterPropertiesSet ((InitializingBean) bean).afterPropertiesSet(); return null ; } },getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { //直接调用afterPropertiesSet ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null ) { String initMethodName = mbd.getInitMethodName(); //判断是否指定了init-method方法,如果指定了init-method方法,则再调用制定的init-method if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet" . equals (initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { //进一步查看该方法的源码,可以发现init-method方法中指定的方法是通过反射实现 invokeCustomInitMethod(beanName, bean, mbd); } } } |
总结:
- spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用
- 实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是init-method方式消除了对spring的依赖
- 如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。
spring中InitializingBean接口使用理解
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法。
测试程序如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service; public class InitBean implements InitializingBean{ public void afterPropertiesSet() throws Exception { System. out .println( "启动时自动执行 afterPropertiesSet..." ); } public void init(){ System. out .println( "init method..." ); } } |
配置文件如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?xml version= "1.0" encoding= "UTF-8" ?> <beans xmlns= "http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:context= "http://www.springframework.org/schema/context" xmlns:dubbo= "http://code.alibabatech.com/schema/dubbo" xmlns:mvc= "http://www.springframework.org/schema/mvc" xmlns:aop= "http://www.springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xsi:schemaLocation= "http: //www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http: //www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http: //www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http: //www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http: //www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http: //code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd" default -lazy-init= "true" > <bean id= "initBean" class = "com.netease.nsip.spring.InitBean" init-method= "init" > </bean> </beans> |
Main主程序如下:
1
2
3
4
5
6
7
8
9
10
|
import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext( "classpath:/applicationContext-core.xml" ); context.getBean( "initBean" ); } } |
运行Main程序,打印如下结果:
1
2
|
启动时自动执行 afterPropertiesSet... init method... |
这说明在spring初始化bean的时候,如果bean实现了InitializingBean接口,会自动调用afterPropertiesSet方法。
问题:实现InitializingBean接口与在配置文件中指定init-method有什么不同?由结果可看出,在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,并且同时在配置文件中指定了init-method,系统则是先调用afterPropertiesSet方法,然后在调用init-method中指定的方法。这方式在spring中是怎么实现的?通过查看spring的加载bean的源码类(AbstractAutowireCapableBeanFactory)可看出其中奥妙AbstractAutowireCapableBeanFactory类中的invokeInitMethods讲解的非常清楚,源码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { //判断该bean是否实现了实现了InitializingBean接口,如果实现了InitializingBean接口,则只掉调用bean的afterPropertiesSet方法 boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod( "afterPropertiesSet" ))) { if (logger.isDebugEnabled()) { logger.debug( "Invoking afterPropertiesSet() on bean with name '" + beanName + "'" ); } if (System.getSecurityManager() != null ) { try { AccessController.doPrivileged( new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { //直接调用afterPropertiesSet ((InitializingBean) bean).afterPropertiesSet(); return null ; } },getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { //直接调用afterPropertiesSet ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null ) { String initMethodName = mbd.getInitMethodName(); //判断是否指定了init-method方法,如果指定了init-method方法,则再调用制定的init-method if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet" . equals (initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { //进一步查看该方法的源码,可以发现init-method方法中指定的方法是通过反射实现 invokeCustomInitMethod(beanName, bean, mbd); } } } |
总结:
- spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用
- 实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是init-method方式消除了对spring的依赖
- 如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。
转:spring中InitailizingBean接口的简单理解的更多相关文章
- Spring中Ordered接口简介
目录 前言 Ordered接口介绍 Ordered接口在Spring中的使用 总结 前言 Spring中提供了一个Ordered接口.Ordered接口,顾名思义,就是用来排序的. Spring是一个 ...
- Spring中Bean及@Bean的理解
Spring中Bean及@Bean的理解 Bean在Spring和SpringMVC中无所不在,将这个概念内化很重要,下面分享一下我的想法: 一.Bean是啥 1.Java面向对象,对象有方法和属性, ...
- C#中事件流程的简单理解
C#中事件流程的简单理解 C#中事件基于委托,要理解事件要先理解委托,但是现在我还没想好怎么写委托,如果不懂委托可以先找找委托的文章 事件基于委托,为委托提供了一种发布/订阅机制 一上来就是这句话,很 ...
- spring中InitializingBean接口使用理解
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法. 测试程序如下: imp ...
- spring中InitializingBean接口使用理解(转)
InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法. 测试程序如下: imp ...
- Java集合框架中List接口的简单使用
Java集合框架可以简单的理解为一种放置对象的容器,和数学中的集合概念类似,Java中的集合可以存放一系列对象的引用,也可以看做是数组的提升,Java集合类是一种工具类,只有相同类型的对象引用才可以放 ...
- Spring学习(二)——Spring中的AOP的初步理解[转]
[前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...
- 对Spring中IOC和DI的理解
前几篇讲了Spring中IOC和DI的用法,本篇应该放到三篇之前,但一直没有想到好的讲解方式,后参考https://blog.csdn.net/luoyepiaoxue2014/article/det ...
- spring中ApplicationContextAware接口描述
项目中使用了大量的工厂类,采用了简单工厂模式: 通过该工厂类可以获取指定的处理器bean,这些处理器bean我们是从spring容器中获取的,如何获取,是通过实现ApplicationContextA ...
随机推荐
- char能不能存储一个汉字
答案是肯定的 请参见博客:https://www.cnblogs.com/1017hlbyr/p/6419016.html
- springboot非web项目
使用CommandRunner @SpringBootApplication public class CrmApplication implements ApplicationRunner { @A ...
- Android 使用date set命令修改系统时间
测试环境:android 7.1.1 在adb shell中试图使用 date -s "yyyymmdd.[[[hh]mm]ss]"修改系统系统时间时,会提示 date: Unkn ...
- echarts修改X,Y轴上的颜色
分为2.0和3.0 一.2.0 修改的代码: x轴: xAxis : [ { type : 'category', data : ['<30','30-','40-','50-','60-', ...
- 深入理解AlexNet网络
原文地址:https://blog.csdn.net/luoluonuoyasuolong/article/details/81750190 AlexNet论文:<ImageNet Classi ...
- tfserving 调用deepfm 并预测 java 【参考】
https://blog.csdn.net/luoyexuge/article/details/79941565?utm_source=blogxgwz8 首先是libsvm格式数据生成java代码, ...
- tensorflow二进制文件读取与tfrecords文件读取
1.知识点 """ TFRecords介绍: TFRecords是Tensorflow设计的一种内置文件格式,是一种二进制文件,它能更好的利用内存, 更方便复制和移动,为 ...
- pandas之数据处理操作
1.pandas对缺失数据的处理 我们的数据缺失通常有两种情况: 1.一种就是空,None等,在pandas是NaN(和np.nan一样) 解决方法: 判断数据是否为NaN:pd.isnull(df) ...
- python 类中__int__和__str__的使用
class F: def __str__(self): return 'hello china' def __int__(self): return 123 res = F()print(res) # ...
- 007. Reverse Integer
题目链接:https://leetcode.com/problems/reverse-integer/description/ Given a 32-bit signed integer, rever ...