上几节我们比较详细地说明了一下BeanFactoryPostProcessor和BeanPostProcessor这2个接口的作用和意义,并且也花了一个章节,讲了一下BeanFactory和FactoryBean的关系,最后我们也稍微说明了一下BeanFactoryAware和BeanNameAware这两个接口的作用,这一节,将开始讲一下,一个bean在被spring管理的时候,初始化时的顺序
我们定义一个简单的bean实现BeanFactoryPostProcessor,BeanPostProcessor,BeanNameAware,
BeanFactoryAware,InitializingBean这些接口,并且调用init-method,我们观察一下这些接口的具体实现的顺序,为我们下一节分析refresh做好最后的准备
照旧上代码
SpringSimpleMultiBean.java
package org.study.spring.springinit; 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.InitializingBean; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; public class SpringSimpleMultiBean implements BeanFactoryAware,BeanNameAware,BeanFactoryPostProcessor,BeanPostProcessor,InitializingBean{ private Integer id; private String name; /** * 构造函数 */ public SpringSimpleMultiBean() { System.out.println("构造函数 init"); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } /** * init-method */ public void initMethod(){ System.out.println("init method Begin"); } public void say(){ System.out.println("hello I am "+name); } /** * InitializingBean接口的具体实现 */ public void afterPropertiesSet() throws Exception { System.out.println("InitializingBean接口的具体实现 begin and id is "+ id +" and name is "+ name); } /** * BeanPostProcessor接口 before 初始化 */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeanPostProcessor接口 before 初始化 postProcessAfterInitialization begin"); return bean; } /** * BeanPostProcessor接口after 初始化 */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeanPostProcessor接口after 初始化 postProcessAfterInitialization begin"); return bean; } /** * BeanFactoryPostProcessor 接口初始化 */ public void postProcessBeanFactory( ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("BeanFactoryPostProcessor 接口初始化 begin and this beanFactory is "+beanFactory); } /** * BeanNameAware初始化 */ public void setBeanName(String name) { System.out.println("BeanNameAware初始化 set BeanName begin and name is "+name); } /** * BeanFactoryName初始化 */ public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("BeanFactoryName初始化 begin and beanFactory is "+beanFactory); } }spring-init.xml
<?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:mybatis-spring="http://mybatis.org/schema/mybatis-spring" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> <bean id="springMultiBean" class="org.study.spring.springinit.SpringSimpleMultiBean" init-method="initMethod"> <property name="id" value="1"/> <property name="name" value="spring"/> </bean> <!-- <bean id="springOtherBean" class="org.study.spring.springinit.SpringOtherBean"></bean> --> </beans>SpringSimpleMultiBeanTest.java
package org.study.spring.springinit; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringSimpleMultiBeanTest { @Test public void test2() throws Exception{ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-init.xml"); SpringSimpleMultiBean bean = applicationContext.getBean("springMultiBean",SpringSimpleMultiBean.class); bean.say(); // SpringOtherBean springOtherBean = applicationContext.getBean("springOtherBean",SpringOtherBean.class); // springOtherBean.say(); } }运行结果:
好了,我发现我不贴代码已经说明不了问题了,语言能力太差,我们先来看看结果吧~
①首先执行的是构造函数
②然后执行的BeanNameAware这个接口中的方法
③然后执行的是BeanFactoryAware这个接口中的方法
④执行InitializingBean接口中的afterPropertiesSet的方法
⑤执行我们在xml中定义的init-method这个方法
⑥最后执行的是BeanFactoryPostProcessor这个方法
这个执行结果我们可以清晰的了解spring的初始化流程,但你可以看出BeanPostProcessor并没有初始化,这是为什么呢?
我们再次打开BeanPostProcessor.java的源代码
翻译一下:应用这个BeanPostProcessor来返回一个新的bean的实例,当任何Bean回调的时候~
请注意是回调~
好吧,意思很明显,当其他非实现BeanPostProcessor的bean且在同一个容器的bean在初始化的时候,才会回调这个方法,所以这就理解了,为什么,我们这边没有执行的原因了,因为此时spring就管理了一个bean,没有其他的bean,何来的回调呢?
好吧,我们打开上面代码的SpringSimpleMultiBeanTest.java中17~18行的注释,spring-init.xml中19行的注释
好了,这次运行了,最后盗图一张
好了,spring的组件我们讲了好几个了,也讲了这些组件在spring初始化bean时候执行的顺序,下一节我们分析refresh()这个方法,应该会理解为什么会是这个执行顺序了,END~