理解spring bean 的生命周期,就能熟悉spring Ioc容器的初始化流程,就知道它有哪些扩展点,能给写框架或者业务都带来很多便利。
1、代码演示bean生命周期
public class SpringLifecycleDemo implements BeanFactoryPostProcessor, InstantiationAwareBeanPostProcessor, BeanPostProcessor {
public SpringLifecycleDemo() {
System.out.println("SpringLifecycleDemo 实例化");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("在beanDefinition之后,bean实例化之前调用:BeanFactoryPostProcessor.postProcessBeanFactory");
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("在bean:" + beanName + "实例化之前调用:InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation");
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("在bean:" + beanName + "实例化之后调用:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation");
return true;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
System.out.println("postProcessProperties");
return pvs;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在bean " + beanName + "初始化之前调用: postProcessBeforeInitialization");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("在bean " + beanName + "初始化之后调用:postProcessAfterInitialization");
return bean;
}
}
public class OtherBean implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, ApplicationContextAware, InitializingBean , DisposableBean {
public OtherBean() {
System.out.println("otherBean 实例化!");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("OtherBean setBeanClassLoader!");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("OtherBean setBeanFactory!");
}
@Override
public void setBeanName(String name) {
System.out.println("OtherBean setBeanName!");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("OtherBean afterPropertiesSet!");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("OtherBean setApplicationContext!");
}
@Override
public void destroy() throws Exception {
System.out.println("OtherBean destroy!");
}
}
public class AnotherBean implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
public AnotherBean() {
System.out.println("AnotherBean 实例化!");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println(" AnotherBean setBeanClassLoader!");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("AnotherBean setBeanFactory!");
}
@Override
public void setBeanName(String name) {
System.out.println("AnotherBean setBeanName!");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("AnotherBean afterPropertiesSet!");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("AnotherBean setApplicationContext!");
}
@Override
public void destroy() throws Exception {
System.out.println("AnotherBean destroy!");
}
}
public class SpringTest {
public static void main(String[] args) {
ApplicationContext ctx =
new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
}
}
applicationContext.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.xsd">
<bean class="com.example.demo.spring.SpringLifecycleDemo"></bean>
<bean class="com.example.demo.spring.OtherBean"></bean>
<bean class="com.example.demo.spring.AnotherBean"></bean>
</beans>
运行main方法得到如下结果:
SpringLifecycleDemo 实例化
在beanDefinition之后,bean实例化之前调用:BeanFactoryPostProcessor.postProcessBeanFactory
在bean:com.example.demo.spring.OtherBean#0实例化之前调用:InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
otherBean 实例化!
在bean:com.example.demo.spring.OtherBean#0实例化之后调用:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
postProcessProperties
OtherBean setBeanName!
OtherBean setBeanClassLoader!
OtherBean setBeanFactory!
OtherBean setApplicationContext!
在bean com.example.demo.spring.OtherBean#0初始化之前调用: postProcessBeforeInitialization
OtherBean afterPropertiesSet!
在bean com.example.demo.spring.OtherBean#0初始化之后调用:postProcessAfterInitialization
在bean:com.example.demo.spring.AnotherBean#0实例化之前调用:InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
AnotherBean 实例化!
在bean:com.example.demo.spring.AnotherBean#0实例化之后调用:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
postProcessProperties
AnotherBean setBeanName!
AnotherBean setBeanClassLoader!
AnotherBean setBeanFactory!
AnotherBean setApplicationContext!
在bean com.example.demo.spring.AnotherBean#0初始化之前调用: postProcessBeforeInitialization
AnotherBean afterPropertiesSet!
在bean com.example.demo.spring.AnotherBean#0初始化之后调用:postProcessAfterInitialization
这里的bean初始化流程就一目了然了。
1)其中BeanFactoryPostProcessor, InstantiationAwareBeanPostProcessor, BeanPostProcessor
实现这三个接口里面的方法是容器级的调用,就是说这些方法除了实现方法本身的bean以外的每一个bean的生命周期过程中都会被调用。(例子中,实例化了两个bean,方法只实现了一次,被调用了两次)
2)其他接口的方法是bean生命周期级的,就是只有在实现了这些接口的bean的生命周期才会被调用,只调用一次。(例子中,实例化了两个bean,方法实现了两次,被调用了两次)
3)在spring Ioc容器的初始化过程中,它会最先初始化实现了容器生命周期接口的bean。(比如本利中的SpringLifecycleDemo)