做一个合格的程序猿之浅析Spring IoC源码(十)Spring Bean的初始化顺序

上几节我们比较详细地说明了一下BeanFactoryPostProcessor和BeanPostProcessor这2个接口的作用和意义,并且也花了一个章节,讲了一下BeanFactory和FactoryBean的关系,最后我们也稍微说明了一下BeanFactoryAware和BeanNameAware这两个接口的作用,这一节,将开始讲一下,一个bean在被spring管理的时候,初始化时的顺序

我们定义一个简单的bean实现BeanFactoryPostProcessorBeanPostProcessor,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的源代码

做一个合格的程序猿之浅析Spring IoC源码(十)Spring Bean的初始化顺序_第1张图片

翻译一下:应用这个BeanPostProcessor来返回一个新的bean的实例,当任何Bean回调的时候~


请注意是回调~


好吧,意思很明显,当其他非实现BeanPostProcessor的bean且在同一个容器的bean在初始化的时候,才会回调这个方法,所以这就理解了,为什么,我们这边没有执行的原因了,因为此时spring就管理了一个bean,没有其他的bean,何来的回调呢?


好吧,我们打开上面代码的SpringSimpleMultiBeanTest.java中17~18行的注释,spring-init.xml中19行的注释


好了,这次运行了,最后盗图一张

做一个合格的程序猿之浅析Spring IoC源码(十)Spring Bean的初始化顺序_第2张图片


好了,spring的组件我们讲了好几个了,也讲了这些组件在spring初始化bean时候执行的顺序,下一节我们分析refresh()这个方法,应该会理解为什么会是这个执行顺序了,END~




你可能感兴趣的:(执行顺序,Spring初始化)