Bean的生命周期
Bean的生命周期主要分为4个阶段
- 实例化(Instantiation):实例化Bean对象
- 属性赋值(Populate):为Bean设置相关的属性和依赖
- 初始化(Initialization):包括Aware接口处理,BeanPostProcessor前置处理,InitializingBean接口处理,init-method方法执行,BeanPostProcessor后置处理
- 销毁(Destruction):
Bean的生命周期过程如图所示:
Bean的创建过程主要在AbstractAutowireCapableBeanFactory类中的doCreateBean()方法中实现:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {
// 实例化Bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// ...
Object exposedObject = bean;
try {
// 属性赋值
populateBean(beanName, mbd, instanceWrapper);
// 初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
// ...
// 销毁-注册回调接口
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
return exposedObject;
}
其中initializeBean()方法对应图中的3~7步,具体实现也是在AbstractAutowireCapableBeanFactory类中:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 检查Aware相关的接口并设置相关依赖
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
// BeanPostProcessor前置处理
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 实现了InitializingBean接口,调用afterPropertiesSet()方法
// 若配置了init-method方法,则执行
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// BeanPostProcessor后置处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
// invokeInitMethods()同样也在AbstractAutowireCapableBeanFactory类中
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {
// 判断是否实现了InitializingBean接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
// 判断是否有init-method方法
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
销毁的过程和初始化的过程类似,判断是否实现DisposableBean接口以及是否有实现destory-method方法
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
// 若实现DisposableBean接口,则执行destory()方法
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
}
else {
((DisposableBean) this.bean).destroy();
}
}
}
// 配置了自定义的destory-method方法,则执行
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
Bean初始化的扩展点
Aware接口
若Spring检测到bean实现了Aware接口,则会为其注入相应的依赖,通过让bean实现Aware接口,则能在bean中获得相应的Spring容器资源。Spring提供的Aware接口有:
- BeanNameAware:注入当前bean对应的beanName
- BeanClassLoaderAware:注入当前bean的ClassLoader
- BeanFactoryAware:注入当前BeanFactory容器的引用
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
Aware是知道的,已感知的意思,所以这些Aware接口时让实现接口的类可以感知到这些Aware接口获取的内容。例如BeanNameAware,实现了BeanNameAware接口,就可以让Bean感知到自身的BeanName,对应于Spring配置<bean id="xxx" class="xxx">中id属性
public interface BeanNameAware extends Aware {
void setBeanName(String name);
}
BeanNameAware使用得具体实例:
- 定义两个类,一个实现BeanNameAware,一个不实现BeanNameAware 实现BeanNameAware接口
public class ClassOne implements BeanNameAware {
private String id;
private String name;
@Override
public void setBeanName(String beanName){
this.id = beanName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString(){
return "[id = "+this.id+", "+"name = "+this.name+"]";
}
}
不实现BeanNameAware接口
public class ClassTwo {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString(){
return "[id = "+this.id+", "+"name = "+this.name+"]";
}
}
- 两个类定义在Spring的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 id="classOne" class="ClassOne">
<property name="name" value="one"/>
</bean>
<bean id="classTwo" class="ClassTwo">
<property name="name" value="one"/>
</bean>
</beans>
- 在测试类中获取该Bean,并打印具体的值
public class MyTest {
@Test
public void MyBean(){
ApplicationContext context = new ClassPathXmlApplicationContext("application_context.xml");
ClassOne classOne=context.getBean(ClassOne.class);
System.out.println(classOne);
ClassTwo classTwo=context.getBean(ClassTwo.class);
System.out.println(classTwo);
}
}
// 打印结果
[id = classOne, name = one]
[id = null, name = one]
BeanPostProcessor
BeanPostProcessor是Spring为修改Bean提供的强大扩展点,其可作用于容器的所有bean
public interface BeanPostProcessor {
// 初始化前置处理
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// 初始化后置处理
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
InitializingBean和init-method
InitializingBean和init-method是Spring为bean初始化提供的扩展点。
可以在InitializingBean中的afterPropertiesSet()方法中写初始化逻辑
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
可以通过Spring-xml文件中指定bean的init-method方法
<?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 id="test" class="Test" init-method="init()"/>
</beans>
总结
- Spring Bean的生命周期主要有实例化,属性赋值,初始化,销毁4个阶段
- 初始化时,有Aware接口的依赖注入,BeanPostProcessor在初始化前后的处理,以及InitializingBean和init-method执行初始化操作