Spring-Bean初始化顺序
2016-09-01 18:07
399 查看
在验证Spring-Bean初始化顺序前,先看几个关键接口
InitializingBean
Spirng的InitializingBean为bean提供了定义初始化方法的方式。InitializingBean是一个接口,它仅仅包含一个方法:afterPropertiesSet()。
在spring 初始化后,执行完所有属性设置方法(即setXxx)将自动调用 afterPropertiesSet(), 在配置文件中无须特别的配置, 但此方式增加了bean对spring 的依赖,应该尽量避免使用
init-method(非接口)
Spring虽然可以通过InitializingBean完成一个bean初始化后对这个bean的回调,但是这种方式要求bean实现 InitializingBean接口。一但bean实现了InitializingBean接口,那么这个bean的代码就和Spring耦合到一起了。通常情况下我不鼓励bean直接实现InitializingBean,可以使用Spring提供的init-method的功能来执行一个bean 子定义的初始化方法。
BeanFactoryPostProcessor接口
可以在spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。
注意:BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的。接口方法的入参是ConfigurrableListableBeanFactory,使用该参数,可以获取到相关bean的定义信息
BeanPostProcessor接口
BeanPostProcessor,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。这里说的初始化方法,指的是下面两种:
1)bean实现了InitializingBean接口,对应的方法为afterPropertiesSet
2)在bean定义的时候,通过init-method设置的方法
注意:BeanPostProcessor是在spring容器加载了bean的定义文件并且实例化bean之后执行的。BeanPostProcessor的执行顺序是在BeanFactoryPostProcessor之后。
代码:
配置文件:
测试方法:
执行结果:
调用HelloWorld构造器...
调用setHello()...
调用BeanNameAware.setBeanName
调用BeanFactoryAware.setBeanFactory
调用InitializingBean的afterPropertiesSet()...
HelloWorld类init 方法
调用BeanFactoryPostProcessor的postProcessBeanFactory()...
HelloWorld [hello=hello]
DisposableBean 接口 destroy方法
由结果得出初始化be
4000
an顺序
1.构造函数
2.初始化属性
3.如果实现了BeanFactoryAware 接口执行setBeanFactory方法
4..如果实现了InitializingBean 接口执行afterPropertiesSet方法
5.如果在配置文件中指定了init-method,那么执行该方法
6..如果实现了BeanFactoryPostProcessor 接口在 “new”其他类之前执行 postProcessBeanFactory 方法(通过这个方法可以改变配置文件里面的属性值的配置)
7.如果实现了BeanPostProcessor 接口,那么会在其他bean初始化方法之前执行postProcessBeforeInitialization 方法,之后执行postProcessAfterInitialization方法
感觉奇怪的地方就是没有执行destroy方法
在此方法中没有执行接口BeanPostProcessor的方法,不知道何原因
InitializingBean
Spirng的InitializingBean为bean提供了定义初始化方法的方式。InitializingBean是一个接口,它仅仅包含一个方法:afterPropertiesSet()。
在spring 初始化后,执行完所有属性设置方法(即setXxx)将自动调用 afterPropertiesSet(), 在配置文件中无须特别的配置, 但此方式增加了bean对spring 的依赖,应该尽量避免使用
init-method(非接口)
Spring虽然可以通过InitializingBean完成一个bean初始化后对这个bean的回调,但是这种方式要求bean实现 InitializingBean接口。一但bean实现了InitializingBean接口,那么这个bean的代码就和Spring耦合到一起了。通常情况下我不鼓励bean直接实现InitializingBean,可以使用Spring提供的init-method的功能来执行一个bean 子定义的初始化方法。
BeanFactoryPostProcessor接口
可以在spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改,例如可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。
注意:BeanFactoryPostProcessor是在spring容器加载了bean的定义文件之后,在bean实例化之前执行的。接口方法的入参是ConfigurrableListableBeanFactory,使用该参数,可以获取到相关bean的定义信息
BeanPostProcessor接口
BeanPostProcessor,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。这里说的初始化方法,指的是下面两种:
1)bean实现了InitializingBean接口,对应的方法为afterPropertiesSet
2)在bean定义的时候,通过init-method设置的方法
注意:BeanPostProcessor是在spring容器加载了bean的定义文件并且实例化bean之后执行的。BeanPostProcessor的执行顺序是在BeanFactoryPostProcessor之后。
代码:
<span style="font-size:14px;">package cn.com.init; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; public class HelloWorld implements InitializingBean, BeanPostProcessor, BeanFactoryPostProcessor, BeanFactoryAware, BeanNameAware, DisposableBean { public HelloWorld() { System.out.println("调用HelloWorld构造器..."); } private String hello; public String getHello() { return hello; } public void setHello(String hello) { this.hello = hello; System.out.println("调用setHello()..."); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("调用BeanPostProcessor的postProcessBeforeInitialization()..."); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("调用BeanPostProcessor的postProcessAfterInitialization()..."); return bean; } @Override public void afterPropertiesSet() throws Exception { System.out.println("调用InitializingBean的afterPropertiesSet()..."); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory paramConfigurableListableBeanFactory) throws BeansException { System.out.println("调用BeanFactoryPostProcessor的postProcessBeanFactory()..."); } @Override public String toString() { return "HelloWorld [hello=" + hello + "]"; } @Override public void setBeanName(String paramString) { System.out.println("调用BeanNameAware.setBeanName"); } @Override public void setBeanFactory(BeanFactory paramBeanFactory) throws BeansException { System.out.println("调用BeanFactoryAware.setBeanFactory"); } @Override public void destroy() throws Exception { System.out.println("DisposableBean 接口 destroy方法"); } public void init() throws Exception { System.out.println("HelloWorld类init 方法"); } } </span>
配置文件:
<span style="font-size:14px;"><?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:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd" default-lazy-init="false"> <!-- <bean id="myJavaBean" class=" cn.com.init.MyJavaBean" init-method="initMethod"> <property name="desc" value="原始的描述信息" /> <property name="remark" value="原始的备注信息" /> </bean> <bean id="myBeanPostProcessor" class=" cn.com.init.MyBeanPostProcessor" /> <bean id="myBeanFactoryPostProcessor" class=" cn.com.init.MyBeanFactoryPostProcessor" /> --> <bean id="hello" class="cn.com.init.HelloWorld" init-method="init" > <property name="hello" value="hello" /> </bean> </beans></span>
测试方法:
<span style="font-size:14px;">package mybatis; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.com.init.HelloWorld; import junit.framework.TestCase; public class BeanPostPorcessorTest extends TestCase { private ClassPathXmlApplicationContext context; protected void setUp() throws Exception { super.setUp(); String[] paths = {"classpath*:spring-text.xml"}; context = new ClassPathXmlApplicationContext(paths); } public void testBeanFactoryPostProcessor() { HelloWorld bean = (HelloWorld) context.getBean("hello"); System.out.println(bean); context.getBeanFactory().destroySingletons(); } } </span>
执行结果:
调用HelloWorld构造器...
调用setHello()...
调用BeanNameAware.setBeanName
调用BeanFactoryAware.setBeanFactory
调用InitializingBean的afterPropertiesSet()...
HelloWorld类init 方法
调用BeanFactoryPostProcessor的postProcessBeanFactory()...
HelloWorld [hello=hello]
DisposableBean 接口 destroy方法
由结果得出初始化be
4000
an顺序
1.构造函数
2.初始化属性
3.如果实现了BeanFactoryAware 接口执行setBeanFactory方法
4..如果实现了InitializingBean 接口执行afterPropertiesSet方法
5.如果在配置文件中指定了init-method,那么执行该方法
6..如果实现了BeanFactoryPostProcessor 接口在 “new”其他类之前执行 postProcessBeanFactory 方法(通过这个方法可以改变配置文件里面的属性值的配置)
7.如果实现了BeanPostProcessor 接口,那么会在其他bean初始化方法之前执行postProcessBeforeInitialization 方法,之后执行postProcessAfterInitialization方法
感觉奇怪的地方就是没有执行destroy方法
在此方法中没有执行接口BeanPostProcessor的方法,不知道何原因
相关文章推荐
- spring初始化bean的顺序
- Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
- Spring-Bean初始化顺序
- Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
- Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
- Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
- Spring初始化Bean的顺序
- 详解Spring 中如何控制2个bean中的初始化顺序
- 做一个合格的程序猿之浅析Spring IoC源码(十)Spring Bean的初始化顺序
- Spring中Bean的初始化顺序
- Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
- spring bean初始化顺序
- Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
- Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
- Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
- Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
- Spring面试题之如何控制Bean初始化顺序
- 在Spring容器中Bean的几种初始化、销毁方法的实现和先后顺序
- Spring容器中的Bean几种初始化方法和销毁方法的先后顺序
- BeanFactoryAware在InitializingBean之后执行,奇怪的Spring初始化顺序?