Spring源码学习笔记(8)——Bean的生命周期
一. Bean生命周期简介
Bean的声明周期是指Bean从创建、初始化到销毁的整个过程。在Spring中,Bean的生命周期都是交给IoC容器管理的。Bean的主要生命周期主要有四个阶段:
- 实例化
- 属性赋值
- 初始化
- 销毁
Spring的IoC容器在管理Bean生命周期的同时,也提供了多种方式实现Bean在不同生命周期阶段的扩展,下面分别进行介绍。
二. init-method和destroy-method
在配置一个Bean的时候,可以通过init-method和destroy-method属性配置Bean的初始化和销毁方法,配置文件形式和注解形式方式相同。下面配置了一个Bean,并指定了其初始化和销毁方法。
/**
* @Auther: ZhangShenao
* @Date: 2018/9/28 16:45
* @Description:
*/
public class Car {
public Car(){
System.err.println("Car Construct...");
}
public void init(){
System.err.println("Car Init...");
}
public void destroy(){
System.err.println("Car Destroy...");
}
}
/**
* @Auther: ZhangShenao
* @Date: 2018/9/21 10:15
* @Description:Spring配置类
*/
@Configuration
@ComponentScan
public class MainConfig {
//装配一个Car实例,并指定其初始化和销毁方法
@Bean(initMethod = "init",destroyMethod = "destroy")
public Car car(){
return new Car();
}
}
注:
- 对于Singleton的Bean,Bean的实例是在容器启动时创建,初始化方法是在Bean被创建出来且对属性赋值后执行,销毁方法是在容器关闭之前执行;
- 对于Prototype的Bean,Bean的实例是在每次获取时创建,初始化方法也是在每次创建Bean实例后执行,而IoC容器并不管理Prototype类型Bean的销毁方法。
三. InitializingBean和DisposableBean接口
InitializingBean和DisposableBean是Spring提供的两个Bean的生命周期相关的接口。这两个接口都只有一个方法,见源码:
public interface InitializingBean {
//该方法在Bean创建出来并且所有属性都被赋值后调用
void afterPropertiesSet() throws Exception;
}
public interface DisposableBean {
//该方法在单实例对象被销毁之前调用
void destroy() throws Exception;
}
组件可以实现这两个接口,以实现自定义的初始化和销毁方法,这里不再赘述。
四. @PostConstruct和@PreDestroy注解
@PostConstruct和@PreDestroy是JSR250规范中定义的Bean生命周期的相关注解,可以标记在自定义方法上,表示该方法是初始化/销毁方法,注解定义如下:
@Documented
@Retention (RUNTIME)
@Target(METHOD)
//标记了该注解的方法,会在对应Bean创建完成、属性赋值完成和依赖注入完成之后调用
public @interface PostConstruct {
}
@Documented
@Retention (RUNTIME)
@Target(METHOD)
//当Bean被从容器中移除后,会触发一个回调通知,标记了该注解的方法会接收到该通知,处理自定义的销毁逻辑
public @interface PreDestroy {
}
@PostConstruct和@PreDestroy这两个注解相比于接口的方式,处理更加灵活。
五. BeanPostProcessor后处理器
BeanPostProcessor是Spring体系中非常重要的一个组件,它可以拦截Bean的初始化过程,在Bean初始化前后增加额外的逻辑。
BeanPostProcessor接口有两个方法,分别是Bean初始化前置处理和初始化后置处理,见源码:
public interface BeanPostProcessor {
//初始化前置处理方法,该方法在InitializingBean的afterPropertiesSet()和自定义init-method等初始化方法之前执行,执行该方法之前,Bean的属性已经赋值完毕。
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
//初始化后置处理方法,在在InitializingBean的afterPropertiesSet()和自定义init-method等方法后执行
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
BeanPostProcessor除了可以增加额外的初始化处理之外,一个更加重要的功能是:BeanPostProcessor可以拦截Bean的初始化,返回一个目标Bean的代理对象。BeanPostProcessor的具体原理将在后面章节中详细介绍。
六. BeanPostProcessor在Spring框架中的应用
Spring框架底层使用了大量BeanPostProcessor的实现类,很多Spring的重要功能,如@Autowired注解的自动注入、@Scheduled注解的任务调度和xxxAware等功能都是基于BeanPostProcessor实现的。下面以简单的ApplicationContextAwareProcessor为例,进行源码的解析:
如果想在一个非Spring Bean的类中获取ApplicationContext实例,可以实现ApplicationContextAware接口的setApplicationContext()方法,如下所示:
/**
* @Auther: ZhangShenao
* @Date: 2018/9/29 08:35
* @Description:
*/
public class ApplicationContextHolder implements ApplicationContextAware{
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
这样,就拿到了IoC容器的ApplicationContext对象,以进行更多的操作。ApplicationContextAware接口就是使用ApplicationContextAwareProcessor后处理器支持的,源码:
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareInterfaces(bean);
return null;
}
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
private static class EmbeddedValueResolver implements StringValueResolver {
private final ConfigurableBeanFactory beanFactory;
public EmbeddedValueResolver(ConfigurableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public String resolveStringValue(String strVal) {
return this.beanFactory.resolveEmbeddedValue(strVal);
}
}
}
在ApplicationContextAwareProcessor的postProcessBeforeInitialization中,会调用invokeAwareInterfaces()方法,根据bean实现的接口类型,将相应的ApplicationContext注入到bean中。
七. Bean生命周期源码解析
下面结合源码,总结下Bean的生命周期:
Spring的IoC容器创建Bean的核心逻辑在AbstractAutowireCapableBeanFactory的doCreateBean()方法中,见源码:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
//创建Bean实例,如果是Singleton的Bean,尝试从缓存中获取,如果缓存中不存在,则创建新的实例并放入缓存中
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
//调用所有注册的MergedBeanDefinitionPostProcessor处理器的postProcessMergedBeanDefinition,定制特殊的BeanDefinition
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
Object exposedObject = bean;
try {
//为Bean的属性赋值
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
//执行Bean的初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
//如果bean实现了DisposableBean或者注册了destroy-method,则注册销毁处理
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
doCreateBean()方法涵盖了Bean的创建、初始化和销毁的整个生命周期。下面针对每个过程进行详细叙述:
-
Bean的创建
首先会根据beanName获取BeanWrapper。如果是Singleton类型的Bean,首先尝试从缓存中获取,缓存中不存在时再创建新的;Prototype类型的Bean则是每次都创建新实例。创建Bean实例的方法在doCreateBean()中:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { //解析bean的Class Class<?> beanClass = resolveBeanClass(mbd, beanName); //校验bean的Class是否为public的 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } //如果bean声明了工厂方法,则调用工厂方法创建 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { return instantiateBean(beanName, mbd); } } //如果存在SmartInstantiationAwareBeanPostProcessor,则使用determineCandidateConstructors方法返回的构造器创建Bean Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } //没有特殊构造器,则直接调用Bean的默认无参构造创建实例 return instantiateBean(beanName, mbd); }
默认情况下,Spring会使用Bean的默认无参构造器创建Bean实例。如果容器中存在SmartInstantiationAwareBeanPostProcessor后处理器,为某些Bean指定了特殊的构造器,则使用该构造器创建对象。
-
Bean的属性赋值
Bean的属性赋值处理在populateBean()方法中:
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { PropertyValues pvs = mbd.getPropertyValues(); //空对象直接返回 if (bw == null) { if (!pvs.isEmpty()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { return; } } //如果容器中注册了InstantiationAwareBeanPostProcessor,则调用postProcessAfterInstantiation方法对bean的属性进行额外的处理。 boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); //处理基于beanName的属性自动注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } //处理基于beanType的属性自动注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); //调用InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法处理属性赋值后的逻辑 if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } //属性赋值后处理 applyPropertyValues(beanName, mbd, bw, pvs); }
与属性赋值相关的,有一个重要的处理器接口InstantiationAwareBeanPostProcessor,它扩展了BeanPostProcessor接口,增加了bean实例化前、实例化后和属性赋值后的处理,接口定义如下:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { //Bean实例化前处理,可以返回目标Bean的代理对象 Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException; //在Bean实例化后,属性赋值前处理 boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException; //属性赋值后处理 PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException; }
-
Bean的初始化
Bean初始化的处理在initializeBean()方法中:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { //进行xxxAware处理 if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } //遍历所有BeanPostProcessor,调用postProcessBeforeInitialization方法执行初始化前置处理 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,postProcessAfterInitialization方法执行初始化后置处理 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
在initializeBean()方法中可以清晰地看到前面介绍的Bean初始化顺序:首先执行BeanPostProcessor的初始化前置处理,就是遍历所有的BeanPostProcessor,调用其postProcessBeforeInitialization方法,如下:
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessBeforeInitialization(result, beanName); if (result == null) { return result; } } return result; }
接下来,进行初始化,包括InitializingBean的afterPropertiesSet()方法和自定义的init-method初始化方法,在invokeInitMethods()方法中:
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { //如果Bean实现了InitializingBean接口,则调用afterPropertiesSet()方法 boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isDebugEnabled()) { logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { ((InitializingBean) bean).afterPropertiesSet(); return null; } }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { ((InitializingBean) bean).afterPropertiesSet(); } } //调用在配置文件中或@Bean注解中配置的自定义初始化方法, if (mbd != null) { String initMethodName = mbd.getInitMethodName(); if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); } } }
最后,执行BeanPostProcessor的初始化后置处理,逻辑同前置处理类似,源码:
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; }
-
Bean的销毁
Bean销毁方法的注册在registerDisposableBeanIfNecessary()方法中:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { //对于Singleton类型的Bean,如果需要执行销毁方法,则注册DisposableBeanAdapter if (mbd.isSingleton()) { registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { //对与自定义类型的Scope,执行registerDestructionCallback注册销毁回调 Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'"); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } }
对于是否需要执行销毁逻辑的判断在requiresDestruction()方法中:
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) { return (bean != null && (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || hasDestructionAwareBeanPostProcessors())); }
以下三种情况的Bean需要执行销毁逻辑:
- 实现了DisposableBean接口,需调用其destroy()方法;
- 通过配置文件或者@Bean直接注册了销毁方法;
- 容器中存在DestructionAwareBeanPostProcessor后处理器
对于需要执行销毁逻辑的Bean,都调用registerDisposableBean()方法注册了一个DisposableBeanAdapter,源码如下:
/** Disposable bean instances: bean name --> disposable instance */ private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>(); public void registerDisposableBean(String beanName, DisposableBean bean) { synchronized (this.disposableBeans) { this.disposableBeans.put(beanName, bean); } }
DefaultSingletonBeanRegistry使用一个LinkedHashMap维护所有的DisposableBeanAdapter,在容器关闭时调用所有DisposableBeanAdapter的destroy()方法。DisposableBeanAdapter采用了适配器设计模式,将所有实现了DisposableBean接口的Bean和注册了destroy-method方法的Bean都适配成了一个DisposableBeanAdapter,方便进行统一的销毁处理。
八. Bean生命周期流程总结
- 调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法,进行Bean实例化前置处理
- 调用构造器实例化Bean
- populateBean()
- 调用InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法,进行Bean实例化后处理
- 为Bean的属性赋值
- 调用InstantiationAwareBeanPostProcessor.postProcessPropertyValues()方法,进行Bean属性赋值后置处理
- initializeBean()
- 调用BeanPostProcessor.postProcessBeforeInitialization()方法,进行Bean的初始化前置处理
- 执行Bean的初始化方法,如init-method、@PostConstruct、InitializingBean等方式定义的初始化方法
- 调用BeanPostProcessor.postProcessAfterInitialization()方法,进行Bean的初始化后置处理
- 注册销毁方法,如destroy-method、@PreDestroy、DisposableBean等方式定义的销毁方法,将这些销毁逻辑适配成一个DisposableBeanAdapter,注册到容器中,在容器关闭时调用。(销毁方法对于Prototype类型的Bean不生效)