一、简介
理解spring中bean的生命周期,对于学习和使用spring很有帮助。本文将从两个角度对spring中bean
的生命周期进行介绍,一是bean定义生成;二是bean在初始化、使用、销毁的生命周期中经历的阶段。
二、bean定义生成
bean定义生成主要分为三个步骤,即bean定义的获取、bean定义的注册。
1、bean定义的获取
bean的定义来源各种各样,如xml定义、java注解定义等。
spring对各种来源提供了统一的接口org.springframework.core.io.Resource,
Resource接口即也是对spring内的所有底层资源进行了抽象(如file、url、classpath)。
Resource接口相关的类结构图如下:
各类bean定义的加载请参数相应spring源码。
2、bean定义的解析
由于来源的不同,bean的解析也是各种各样的(如xml内标签的解析)。
spring对bean的定义仍然有公共的接口org.springframework.beans.factory.config.BeanDefinition。
具体解析请查看spring源码。
3、bean的注册
解析得到的bean,最终会注册到容器中,其实也就是ConcurrentHashMap,
即org.springframework.beans.factory.support.DefaultListableBeanFactory类中的实例变量
/** Map of bean definition objects, keyed by bean name */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
此bean的加载完成
三、spring的生命周期
spring生命周期中的阶段,包括初始化、使用、销毁。
1、初始化阶段
1)调用bean的构造函数,创建实例;
2)进行参数依赖注入;
3)若实现org.springframework.beans.BeanNameAware接口,则调用BeanNameAware的setBeanName()方法;
4)若实现org.springframework.beans.factory.BeanClassLoaderAware接口,则调用BeanClassLoaderAware的setBeanClassLoader()方法;
5)若实现org.springframework.context.ApplicationContextAware接口,则调用ApplicationContextAware的setApplicationContext()方法;
6)若使用了注解@PostConstruct,则调相应方法;
7)若实现org.springframework.beans.factory.InitializingBean接口,则调用InitializingBean接口的afterPropertiesSet方法;
8)若bean定义的使用了initMethod,则调相应方法;
9)若实现org.springframework.beans.factory.config.BeanPostProcessor接口,则调用BeanPostProcessor的postProcessBeforeInitialization()方法和postProcessAfterInitialization方法;
2、使用阶段
1)bean在项目的使用;
3、销毁阶段
1)若使用注解@PreDestroy,则调用相应方法;
2)若bean定义中配置了destroyMethod,则调用相应方法;
3)若实现org.springframework.beans.factory.DisposableBean接口,则调用DisposableBean接口的destroy方法;
四、bean生命周期示例
1、定义bean文件 SpringBeanLife.class
import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; public class SpringBeanLife implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, InitializingBean, BeanPostProcessor, DisposableBean { private String id; /******************* 下面是方法按时间执行的先后顺序 *************************/ //初始化 SpringBeanLife() { System.out.println("bean init"); } //参数注入 public void setId(String id) { this.id = id; System.out.println("invoke set method"); } //来自BeanNameAware @Override public void setBeanName(String name) { System.out.println("invoke setBeanName"); } //来自BeanClassLoaderAware @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("invoke setBeanClassLoader"); } //来自ApplicationContextAware @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("invoke setApplicationContext"); } //来自注解@PostConstruct @PostConstruct public void postConstructMethod() { System.out.println("invoke postConstructMethod"); } //来自InitializingBean @Override public void afterPropertiesSet() throws Exception { System.out.println("invoke afterPropertiesSet"); } //来自配置initMethod = "initMethod" public void initMethod() { System.out.println("invoke init-method"); } //来自BeanPostProcessor @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("invoke postProcessBeforeInitialization"); return bean; } //来自BeanPostProcessor @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("invoke postProcessAfterInitialization"); return bean; } //bean使用(如此时调用了下面的use方法) public void use() { System.out.println("use bean"); } //来自注解@PreDestroy @PreDestroy public void preDestroyMethod() { System.out.println("invoke preDestroyMethod"); } //来自bean定义中的配置destroyMethod = "destoryMethod" public void destoryMethod() { System.out.println("invoke destory-method"); } //来自DisposableBean @Override public void destroy() throws Exception { System.out.println("invoke destroy"); } }
2、测试
import org.springframework.beans.factory.annotation.Configurable; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; @Configurable public class SpringConfig { @Bean(initMethod = "initMethod", destroyMethod = "destoryMethod") public SpringBeanLife springBeanLife() { SpringBeanLife bean = new SpringBeanLife(); bean.setId("001"); return bean; } public static void main(String[] args) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class); SpringBeanLife bean = ctx.getBean(SpringBeanLife.class); bean.use(); ctx.close(); } }
输出:
bean init
invoke set method
invoke setBeanName
invoke setBeanClassLoader
invoke setApplicationContext
invoke postConstructMethod
invoke afterPropertiesSet
invoke init-method
invoke postProcessBeforeInitialization
invoke postProcessAfterInitialization
invoke postProcessBeforeInitialization
invoke postProcessAfterInitialization
use bean
invoke preDestroyMethod
invoke destroy
invoke destory-method