spring5源码阅读(六)Spring Bean的生命周期详解+Demo


本文分析下bean的生命周期,spring bean从创建到初始化,在到销毁的过程。其中初始化的过程中,spring又为我们留了几个接口,方便我们实现一些特殊的效果。

1 生命周期整体流程

bean的生命周期总结为3大步骤:

  • 实例化
  • 初始化
  • 销毁

在这里插入图片描述

1.1 实例化

前面文章中spring5源码阅读(三)的最后一节,我们分析过,创建bean发生在AbstractAutowireCapableBeanFactory#doCreateBean方法中;实例化和初始化都发生在这里。

实例化本节不着重讲述,我们主要分析下面的初始化过程。

1.2 初始化

初始化发生在AbstractAutowireCapableBeanFactory#doCreateBean的如下一行代码:
exposedObject = initializeBean(beanName, exposedObject, mbd);

初始化过程中相关的接口(注解)有:

  • BeanNameAware#setBeanName
  • BeanFactoryAware#setBeanFactory
  • ApplicationContextAware#setApplicationContext
  • BeanPostProcessor#postProcessBeforeInitialization
  • @PostConstruct
  • InitializingBean#afterPropertiesSet
  • 自定义initMethod方法,通过@Bean或者Xml配置
  • BeanPostProcessor#postProcessAfterInitialization

执行顺序:从上到下。

从后边的demo中可以验证。

1.3 销毁

bean的销毁发生在annotationConfigApplicationContext.close();过程中。

销毁过程中相关的接口(注解)有:

  • @PreDestroy
  • DisposableBean#destroy()
  • 自定义destroyMethod

执行顺序:从上到下。

从后边的demo中可以验证。

2 Demo演示

这里我们主要说初始化和销毁过程中相关的接口。
还是从第一篇文章spring5源码阅读(一)中的demo开始。
重新写一下:

public static void main(String[] args) {
		//这里完成了代理  target---proxy
		AnnotationConfigApplicationContext annotationConfigApplicationContext =
				new AnnotationConfigApplicationContext(Appconfig.class);
	
		annotationConfigApplicationContext.close();
	}

我们在写一个类MyLifeCyc:

public class MyLifeCyc implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {

	@Override
	public void setBeanName(String name) {
		System.out.println(this.getClass().getSimpleName() + "调用BeanNameAware接口的setBeanName方法");
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println(this.getClass().getSimpleName() + "调用BeanFactoryAware接口的setBeanFactory方法");
	}

	@PostConstruct
	public void postConstruct() {
		System.out.println(this.getClass().getSimpleName() + "调用自定义postConstruct方法");
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		System.out.println(this.getClass().getSimpleName() + "调用ApplicationContextAware接口的setApplicationContext方法");
	}

	public void myInit() {
		System.out.println(this.getClass().getSimpleName() + "调用自定义myInit方法");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println(this.getClass().getSimpleName() + "调用InitializingBean接口的afterPropertiesSet方法");
	}

	@Override
	public void destroy() throws Exception {
		System.out.println(this.getClass().getSimpleName() + "调用DisposableBean接口的DisposableBean方法");
	}

	public void myDestroy() throws Exception {
		System.out.println(this.getClass().getSimpleName() + "调用自定义的myDestroy方法");
	}

	@PreDestroy
	public void preDestroy() throws Exception {
		System.out.println(this.getClass().getSimpleName() + "调用自定义的preDestroy方法");
	}
}

再给MyLifeCyc类增加个初始化myInit和销毁方法myDestroy:

@Configuration
@ComponentScan("com.test")
@EnableAspectJAutoProxy
public class Appconfig {
	@Bean(initMethod = "myInit", destroyMethod = "myDestroy")
	MyLifeCyc myLifeCyc() {
		return new MyLifeCyc();
	}
}

执行main方法,有如下输出:

MyLifeCyc调用BeanNameAware接口的setBeanName方法
MyLifeCyc调用BeanFactoryAware接口的setBeanFactory方法
MyLifeCyc调用ApplicationContextAware接口的setApplicationContext方法
MyLifeCyc调用自定义postConstruct方法
MyLifeCyc调用InitializingBean接口的afterPropertiesSet方法
MyLifeCyc调用自定义myInit方法

MyLifeCyc调用自定义的preDestroy方法
MyLifeCyc调用DisposableBean接口的destroy方法
MyLifeCyc调用自定义的myDestroy方法

这里还漏了一点,就是BeanPostProcessor接口;这个接口比较特别的是,它对每个bean都是会发挥作用的,
我们在写一个类MyBeanPostProcessorImpl:

@Service
public class MyBeanPostProcessorImpl implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println(bean.getClass().getSimpleName() + "对象" + beanName + "开始初始化");
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println(bean.getClass().getSimpleName() + "对象" + beanName + "初始化完成");
		return bean;
	}
}

假设我们的项目中还有类A/B/C,那么MyBeanPostProcessorImpl会作用于这3个类,包括上面的MyLifeCyc类。
此时再次执行main方法,输出:


MyLifeCyc调用BeanNameAware接口的setBeanName方法
MyLifeCyc调用BeanFactoryAware接口的setBeanFactory方法
MyLifeCyc调用ApplicationContextAware接口的setApplicationContext方法

MyLifeCyc对象myLifeCyc开始初始化

MyLifeCyc调用自定义postConstruct方法
MyLifeCyc调用InitializingBean接口的afterPropertiesSet方法
MyLifeCyc调用自定义myInit方法

MyLifeCyc对象myLifeCyc初始化完成

MyLifeCyc调用自定义的preDestroy方法
MyLifeCyc调用DisposableBean接口的destroy方法
MyLifeCyc调用自定义的myDestroy方法
发布了62 篇原创文章 · 获赞 29 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/csdn_20150804/article/details/102574974