继上周末肝了一个丐版的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