1.生命周期流程图
上下文ApplicationContext容器中的生命周期:
英文图解:
中文图解:
Spring Bean的生命周期具体流程:
1.Bean容器找到配置文件中Spring Bean的定义。
2.Bean容器利用Java Reflection API创建一个Bean的实例。
3.如果涉及到一些属性值 利用set方法设置一些属性值。
4.如果Bean实现了BeanNameAware接口,调用setBeanName()方法,传入Bean的名字。
5.如果Bean实现了BeanClassLoaderAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
6.如果Bean实现了BeanFactoryAware接口,调用setBeanClassLoader()方法,传入ClassLoader对象的实例。
7.与上面的类似,如果实现了其他*Aware接口,就调用相应的方法。
8.如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行postProcessBeforeInitialization()方法
9.如果Bean实现了InitializingBean接口,执行afterPropertiesSet()方法。
10.如果Bean在配置文件中的定义包含init-method属性,执行指定的方法。
11.如果有和加载这个Bean的Spring容器相关的BeanPostProcessor对象,执行postProcessAfterInitialization()方法
12.当要销毁Bean的时候,如果Bean实现了DisposableBean接口,执行destroy()方法。
13.当要销毁Bean的时候,如果Bean在配置文件中的定义包含destroy-method属性,执行指定的方法。
二.各种接口方法分类
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
1、Bean自身的方法 :这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法
2、Bean级生命周期接口方法 :这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
4、工厂后处理器接口方法 :这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的
工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
三.接口方法介绍
1. Aware接口 (Bean级)
(1)ApplicationContextAware: 获得ApplicationContext对象,可以用来获取所有Bean definition的名字。
(2)BeanFactoryAware : 获得BeanFactory对象,可以用来检测Bean的作用域。
(3)BeanNameAware : 获得Bean在配置文件中定义的名字。
(4)ResourceLoaderAware : 获得ResourceLoader对象,可以获得classpath中某个文件。
(5)ServletContextAware : 在一个MVC应用中可以获取ServletContext对象,可以读取context中的参数。
(6)ServletConfigAware : 在一个MVC应用中可以获取ServletConfig对象,可以读取config中的参数。
Aware接口是针对某个实现这些接口的Bean定制初始化的过程,几个xxxAware接口的作用类似,暂以 BeanNameAware接口为例:
BeanNameAware接口
此接口用于获得Bean在配置文件中定义的名字:Spring Bean存活于容器之中,一般情况下spring bean对context的情况并不了解,如果希望某个bean知道自己在
context中的代号:bean name(一个bean在容器中的id),即可让该bean的类型实现BeanNameAware接口。
示例:
applicationContext.xml
<bean id="javaLanguage" class="org.test.spittr.spi.LanguageBean"> <property name="languageName" value="Java"/> </bean>
实体bean
package org.test.spittr.spi; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource;/ public class LanguageBean implements BeanNameAware { private String languageName; private String beanName; public LanguageBean() { } public String getLanguageName() { return languageName; } public void setLanguageName(String languageName) { this.languageName = languageName; } public void setBeanName(String s) { this.beanName = s; } public String getBeanName() { return beanName; } @Override public String toString() { StringBuilder sb = new StringBuilder(this.getClass().getName()); if(this.getBeanName() != null) { sb.append(": name \‘").append(this.getBeanName()).append("\‘"); } else { sb.append(": unnamed"); } return sb.toString(); } public static void main(String[] args) { Resource resource = new FileSystemResource("/Users/duqi/Downloads/Spittr/src/main/resources/bean-life.xml"); BeanFactory beanFactory = new XmlBeanFactory(resource); LanguageBean languageBean = (LanguageBean) beanFactory.getBean("javaLanguage"); System.out.println(languageBean.getLanguageName()); System.out.println(languageBean.getBeanName()); System.out.println(languageBean.toString()); } }
运行结果:
Java javaLanguage org.test.spittr.spi.LanguageBean: name ‘javaLanguage‘
2. BeanPostProcessor接口(容器级)
(1)如果说上述几个xxxAware接口的作用是定制单个bean的初始化过程,那么BeanPostProcessor接口则可以提供全局的、定制多个bean的初始化过程,只需提供一个实现BeanPostProcessor接口的类即可。
(2)该接口中包含两个方法,postProcessBeforeInitialization和postProcessAfterInitialization。 postProcessBeforeInitialization方法会在容器中的Bean初始化(属性值设置)之前执行, postProcessAfterInitialization方法在容器中的Bean初始化之后执行。
示例:
applicationContext.xml
<bean class="com.giraffe.spring.service.CustomerBeanPostProcessor"/>
实体类
public class CustomerBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("执行BeanPostProcessor的postProcessBeforeInitialization方法,beanName=" + beanName); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("执行BeanPostProcessor的postProcessAfterInitialization方法,beanName=" + beanName); return bean; } }
3. InitializingBean接口 和 DisposableBean接口(Bean级)
这两个接口都只包含一个方法。通过实现InitializingBean接口的afterPropertiesSet()方法可以在Bean属性值设置好之后做一些操作,实现DisposableBean接口的destroy()方法可以在销毁Bean之前做一些操作。
在bean的声明周期中,afterPropertiesSet()方法的调用介于postProcessBeforeInitialization()方法和postProcessAfterInitialization()方法之间。
在实际项目中,可以考虑按照如下模式使用InitializingBean接口:
public class GiraffeService implements InitializingBean,DisposableBean { @Override public void afterPropertiesSet() throws Exception { System.out.println("执行InitializingBean接口的afterPropertiesSet方法"); } @Override public void destroy() throws Exception { System.out.println("执行DisposableBean接口的destroy方法"); } }
这种方法比较简单,但是不建议使用。因为这样会将Bean的实现和Spring框架耦合在一起。