本文主要讨论, 在工厂类将xml文件中配置的Bean标签封装成的BeanDefinition对象后,Bean从创建到销毁的整个执行过程
以下为单例(singleton )bean 情况下,SpringBean的执行顺序(单例bean的创建和管理、销毁过程由Spring统一负责); 而多例(prototype)情况下,spring框架只负责创建,不负责销毁,在外部通过getBean调用时才会创建
1. 单例下SpringBean的生命周期及执行顺序
代码验证
1.1. 定义实体类Test,并实现BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean等接口
public class Test implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
public void init(){
System.out.println(" ++++++++++++ init=method");
}
@PostConstruct
public void postConstruct(){
System.out.println(" ++++++++++++ @PostConstruct");
}
@Override
public void setBeanName(String s) {
System.out.println("------------ BeanNameAware setBeanName : " + s);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("------------ BeanFactoryAware setBeanFactory : " + beanFactory);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("------------ ApplicationContextAware setApplicationContext : " + applicationContext);
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("------------ InitializingBean afterPropertiesSet ");
}
@Override
public void destroy() throws Exception {
System.out.println("------------ DisposableBean destroy ");
}
@PreDestroy
public void PreDestroy() {
System.out.println("------------ @PreDestroy");
}
public void destroyMethod(){
System.out.println("------------ destroy-method");
}
}
1.2.自定义MyBeanPostProcessor类实现BeanPostProcessor,实现Bean的后置处理器
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equalsIgnoreCase("test")){
System.out.println("************* MyBeanPostProcessor postProcessBeforeInitialization: " + bean);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equalsIgnoreCase("test")){
System.out.println("************* MyBeanPostProcessor postProcessAfterInitialization: " + bean);
}
return bean;
}
}
1.3. 定义Test类对应的bean标签信息
<bean id="test" class="com.kay.springLifeCycle.Test" init-method="init" scope="singleton" destroy-method="destroyMethod"></bean>
1.4.测试代码及结果
@Test
public void test7(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
System.out.println("准备通过 applicationContext.getBean(\"test\"); 获取test 对象");
Object test = applicationContext.getBean("test");
System.out.println("获取到的test " + test);
System.out.println("开始调用 applicationContext.destroy() ");
applicationContext.destroy();
}
2.多例bean在 Spring容器初始化时不创建,在外部调用getBean时创建,且spring容器只负责创建不负责销毁,每次getBean时都是返回的新的Bean,长时间未使用的bean由JVM垃圾回收机制回收
2.1修改XML中配置 scope为prototype
<bean id="test" class="com.kay.springLifeCycle.Test" init-method="init" scope="prototype" destroy-method="destroyMethod"></bean>
2.1Test类中增加构造方法
public Test() {
System.out.println("执行 构造方法 ~~~~~~~~~");
}
2.3测试代码及结果
@Test
public void test8(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
System.out.println("准备通过 applicationContext.getBean(\"test\"); 获取test 对象");
Object test1 = applicationContext.getBean("test");
System.out.println("获取到的test1 " + test1);
System.out.println("2 准备通过 applicationContext.getBean(\"test\"); 获取test 对象");
Object test2 = applicationContext.getBean("test");
System.out.println("2 获取到的test " + test2);
System.out.println("开始调用 applicationContext.destroy() ");
applicationContext.destroy();
}
结论:scope设置为多例时,每次返回的对象都是重新创建的,容器启动时不立即创建该bean,每次外部调用getBean时都会重新创建