继上周末肝了一个丐版的Spring IOC容器<zhuanlan.zhihu.com/p/594516378>,在解决循环依赖的时候,知道了 Spring 的 Bean 的大体的创建过程,虽然看过好几次 Bean 生命周期的 Spring 源码,每次也只是“过目而忘”,最近几天也算是肝爽了,就再来看一看Bean的一生吧。
在 IOC 容器启动阶段,容器会把 Bean 的配置信息装载成 BeanDefinition ,BeanDefinition 可以看做成 Bean 的定义信息,然后会经历实例化(Instantiation)、属性赋值(Populate)、初始化(Initalization)和销毁(Destruction)四个阶段。
实例化
实例化前
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