上几节我们比较详细地说明了一下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~