继上周末肝了一个丐版的Spring IOC容器<zhuanlan.zhihu.com/p/594516378>,在处理循环依靠的时候,知道了 Spring 的 Bean 的大体的创立进程,虽然看过好几次 Bean 生命周期的 Spring 源码,每次也仅仅“过目而忘”,最近几天也算是肝爽了,就再来看一看Bean的终身吧。

在 IOC 容器启动阶段,容器会把 Bean 的配置信息装载成 BeanDefinition ,BeanDefinition 可以看做成 Bean 的定义信息,然后会阅历实例化(Instantiation)、特点赋值(Populate)、初始化(Initalization)和毁掉(Destruction)四个阶段。

浅看 Bean 的一生

实例化

实例化前

CODE

AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

完成接口

InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation

resolveBeforeInstantiation(beanName, mbdToUse)

在Spring使用构造器创立bean之前,可以创立一个署理目标回来,完成自定义实例化目标。其实意图就是为了干涉bean的实例化,是在bean的实例化前扩展bean。

实例化

CODE

AbstractAutowireCapableBeanFactory#createBeanInstance

instanceWrapper = this.createBeanInstance(beanName, mbd, args);

实例化后

CODE

AbstractAutowireCapableBeanFactory#populateBean

完成接口

InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation

if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
      continueWithPropertyPopulation = false;
      break;
}

如果该办法回来false,会疏忽特点值的设置;如果回来true,会依照正常流程设置特点值。

特点赋值

CODE

AbstractAutowireCapableBeanFactory#populateBean

完成接口

InstantiationAwareBeanPostProcessor.postProcessProperties

populateBean(beanName, mbd, instanceWrapper);

特点赋值,首要处理@Autowired、@Resource、@Value等注解,也可以通过 postProcessProperties 扩展完成注入。

初始化

CODE

AbstractAutowireCapableBeanFactory#initializeBean

回调Aware接口

invokeAwareMethods(beanName, bean)

BeanNameAware

完成接口

BeanNameAware#setBeanName

if (bean instanceof BeanNameAware) {
    ((BeanNameAware)bean).setBeanName(beanName);
}

回传beanName给bean目标。

BeanClassLoaderAware

完成接口

BeanClassLoaderAware#setBeanClassLoader

if (bean instanceof BeanClassLoaderAware) {
    ClassLoader bcl = this.getBeanClassLoader();
    if (bcl != null) {
         ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
    }
}

回传classLoader给bean目标。

BeanFactoryAware

完成接口

BeanFactoryAware#setBeanFactory

if (bean instanceof BeanFactoryAware) {
	((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}

回传beanFactory给目标。

前置处理

CODE

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

完成接口

BeanPostProcessor#postProcessBeforeInitialization

applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)

BeanPostProcessor,针对一切Spring上下文中一切的bean,进行初始化办法之前的操作。

初始化中

CODE

AbstractAutowireCapableBeanFactory#invokeInitMethods

InitializingBean

完成接口

InitializingBean#afterPropertiesSet

invokeInitMethods(beanName, wrappedBean, mbd)

init-method

		if (mbd != null && bean.getClass() != NullBean.class) {
			String initMethodName = mbd.getInitMethodName();
			if (StringUtils.hasLength(initMethodName) &&
					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}

后置处理

CODE

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

完成接口

BeanPostProcessor#postProcessAfterInitialization

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)

BeanPostProcessor,针对一切Spring上下文中一切的bean,进行初始化办法之后的操作。

毁掉

CODE

AbstractAutowireCapableBeanFactory#registerDisposableBeanIfNecessary

完成接口

DisposableBean#destroy

在spring创立完成bean后会注册相应的毁掉办法。但是不会立马履行,仅仅进行注册。

有 destroy-method等,会注册为可毁掉的bean,在容器封闭时,调用对应的办法进行bean的毁掉。

体会Bean的终身

TestBean

public class TestBean implements BeanNameAware,
        BeanClassLoaderAware,
        BeanFactoryAware,
        ApplicationContextAware,
        InitializingBean,
        DisposableBean {
    private String property;
    private String property2;
    public TestBean(){
        System.out.println("【实例化】1.2--》创立实例");
    }
    public String getProperty() {
        return property;
    }
    public String getProperty2() {
        return property2;
    }
    public void setProperty2(String property2) {
        this.property2 = property2;
        System.out.println("【特点赋值】2.2--》设置property2特点:" + property);
    }
    public void setProperty(String property) {
        this.property = property;
        System.out.println("【特点赋值】2.1--》设置property特点:" + property);
    }
    @Override
    public void setBeanName(String s) {
        System.out.println("【初始化】3.1--》调用Aware接口的办法BeanNameAware#setBeanName");
    }
    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("【初始化】3.2--》调用Aware接口的办法BeanClassLoaderAware#setBeanClassLoader");
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("【初始化】3.3--》调用Aware接口的办法BeanFactoryAware#setBeanFactory");
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("【初始化】3.4--》调用Aware接口的办法ApplicationContextAware#setApplicationContext");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("【初始化】5--》调用InitializingBean#afterPropertiesSet");
    }
    public void initMethod(){
        System.out.println("【初始化】InitializingBean6--》调用init-method");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("【毁掉】8--》调用DisposableBean#destroy");
    }
    public void destroyMethod(){
        System.out.println("【毁掉】9--》调用destroy-method");
    }
}

MyBeanPostProcessor

@Configuration
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【前置处理】4--》履行MyBeanPostProcessor的postProcessBeforeInitialization()办法:+" +beanName);
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("【后置处理】7--》履行MyBeanPostProcessor的postProcessAfterInitialization()办法:+" + beanName);
        return bean;
    }
}

MyInstantiationAwareBeanPostProcessor

public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("【实例化前】1.1--》InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation");
        return null;
    }
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("【实例化后】1.3--》InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation");
        return true;
    }
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.println("【特点赋值】2--》InstantiationAwareBeanPostProcessor调用postProcessPropertyValues办法" +beanName + " " + pvs);
        return pvs;
    }
}

bean.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="testBean"
          class="com.java.syun.oom.TestBean"
          init-method="initMethod" destroy-method="destroyMethod">
        <property name="property" value="Hello World!"/>
        <property name="property2" value="2222"/>
    </bean>
    <bean id="myInstantiationAwareBeanPostProcessor" class="com.java.syun.oom.MyInstantiationAwareBeanPostProcessor"></bean>
    <bean id="myBeanPostProcessor" class="com.java.syun.oom.MyBeanPostProcessor"></bean>
</beans>

ApplicationContextTest

public class Test {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        TestBean testBean = (TestBean) context.getBean("testBean");
        context.close();
    }
}

输出结果

【实例化前】1.1--》InstantiationAwareBeanPostProcessor调用postProcessBeforeInstantiation
【实例化】1.2--》创立实例
【实例化后】1.3--》InstantiationAwareBeanPostProcessor调用postProcessAfterInstantiation
【特点赋值】2--》InstantiationAwareBeanPostProcessor调用postProcessPropertyValues办法testBean PropertyValues: length=2; bean property 'property'; bean property 'property2'
【特点赋值】2.1--》设置property特点:Hello World!
【特点赋值】2.2--》设置property2特点:Hello World!
【初始化】3.1--》调用Aware接口的办法BeanNameAware#setBeanName
【初始化】3.2--》调用Aware接口的办法BeanClassLoaderAware#setBeanClassLoader
【初始化】3.3--》调用Aware接口的办法BeanFactoryAware#setBeanFactory
【初始化】3.4--》调用Aware接口的办法ApplicationContextAware#setApplicationContext
【前置处理】4--》履行MyBeanPostProcessor的postProcessBeforeInitialization()办法:+testBean
【初始化】5--》调用InitializingBean#afterPropertiesSet
【初始化】InitializingBean6--》调用init-method
【后置处理】7--》履行MyBeanPostProcessor的postProcessAfterInitialization()办法:+testBean
【毁掉】8--》调用DisposableBean#destroy
【毁掉】9--》调用destroy-method