简述
Spring是Java生态的代表,我们项目中或多或少都会用到Spring。大家也知道Spring最重要两个功能-IOC和AOP。今天我们来源码分析下Spring Bean生命周期😊。
Spring Bean生命周期分析
代码示例
- pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
仅仅添加spring-context包。
- 添加配置类AppConfig
@Configuration
@ComponentScan("com.example")
public class AppConfig {
}
@Configuration声明AppConfig是一个配置,@ComponentScan扫描会让Spring扫描指定报名下的包。
- 添加OrderDao
@Repository
public class OrderDao {
public void pay() {
System.out.println("Paying...");
}
}
@Repository将OrderDao声明为Bean
- main方法
public class Demo {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
OrderDao orderDao = context.getBean(OrderDao.class);
System.out.println("orderDao:" + orderDao);
orderDao.pay();
context.close();
}
}
知识点
- 我们首先注意Spring中的一个类
BeanDefinition
,他里面是描述了需要转成Bean的类的信息,比如这个类是否单例,Bean的类型,是否懒加载,依赖哪些类,resource,source等信息,具体可以看看BeanDefinition
及其父级。源码中会扫描.class
文件,把.class
文件解析成BeanDefinition
。 Spring Bean
就是由BeanDefinition
中的信息创建的,BeanDefinition
是.class
到Spring Bean
的中间状态。DefaultListableBeanFactory
是BeanFactory
的实现类,我们Spring Bean
是存在DefaultSingletonBeanRegistry
里面的(因为继承关系所以也是存在DefaultListableBeanFactory中)。有几个属性我们需要注意:beanDefinitionMap
用来存放bean对应的BeanDefinitionbeanDefinitionNames
用来存放所有bean的namesingletonObjects
用来存放完整的单例Bean,就是我们经常用到的Spring Bean的缓存earlySingletonObjects
早期单例缓存,也是二级缓存,此缓存的单例Bean没有完全初始化,但是已经经过AOP处理(如果有)。也用于处理Spring Bean循环依赖问题singletonFactories
单例工厂缓存,三级缓存,用于处理Spring Bean循环依赖问题(主要处理AOP)
AbstractAutowireCapableBeanFactory
也是我们需要关注的,BeanDefinition到Spring Bean都是在此类doCreateBean方法中处理。有三个方法需要注意:createBeanInstance
Bean创建,通过反射创建Bean,此时的Bean还是个半成品,没有属性注入和初始化。populateBean
Bean属性填充。此步骤含有解决循环依赖和属性注入等操作。initializeBean
Bean初始化。此步骤中含有调用Aware
方法,在初始化之前使用后置处理器处理,调用实现InitializingBean
中afterPropertiesSet方法,初始化完成后会通过后置处理器进行AOP。
AbstractApplicationContext
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 1. 在这一步中ConfigurationClassPostProcessor会把所有带注释的.class(比如@ComponentScan扫描、@Import、@Configuration等处理)以及后置处理器转化成BeanDefinition
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 2.在这一步中,会把后置处理器先实例化,获得成品Bean并给Spring管理。因为以后Bean三个流程-创建、属性注入以及初始化过程中会穿插各种后置处理器,所以要先实例化。
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 3.实例化剩下非懒加载的Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
最重要的三步在代码中注释了,.class
到BeanDefinition
过程中,是由ConfigurationClassPostProcessor
解析的。当BeanDefinition
都放入beanDefinitionMap
托管后,首先会把后置处理器初始化并交给Spring管理,因为以后BeanDefinition
到Spring Bean
过程中会穿插各种后置处理器,所以要先初始化。最后一步就是会把剩下非懒加载的Bean
实例化。
接下来我们看下部分重要代码。
DefaultListableBeanFactory.preInstantiateSingletons()
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 循环beanDefinitionNames,处理所有的BeanDefinition
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断是否FactoryBean,是的话进行相应处理
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 获取成品Bean,Bean初始化流程也在里面
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
// 从Spring管理中查询单例Bean是否实初始化,如果初始化了并且实现了SmartInitializingSingleton接口,那么会回调此方法。
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
以上最重要的步骤是getBean()
,获取已经实例化后的Bean。
此方法整个流程主要是获取成品Bean,如果Bean还没初始化则进行Bean生命周期,实例化后最后判断Bean是否实现了SmartInitializingSingleton接口,是的话会回调此方法。
AbstractBeanFactory.doGetBean()
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 从缓存中获取Bean,如果Bean不存在则实例化初始化,如果存在则做些处理后返回。
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 省略...
try {
// 省略...
// Create bean instance.
if (mbd.isSingleton()) {
// 这里会把成品Bean放入缓存
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建Bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 省略...
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 省略...
return (T) bean;
}
在doGetBean()方法中,我们先调用getSingleton()方法从缓存中获取一下Bean,这里获取到的Bean有可能是成品Bean,有可能是从二级缓存获取到半成品Bean,也可能获取到的是三级缓存-单例工厂缓存。这里涉及到循环依赖解决方案问题,以后再说。
获取不到的话,我们会通过createBean()方法创建Bean,并且通过getSingleton()把Bean放入Spring容器中。
AbstractAutowireCapableBeanFactory.doCreateBean()
此方法是createBean往后的调用,创建Bean整个流程的方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 1.实例化Bean,此时的Bean只是个半成品,没有进行属性注入和初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// CommonAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor这一类处理器解析Bean的注解信息,放入injectionMetadataCache中,后面属性注入会用到。
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 判断Bean是否放到singletionFactories中,为了解决循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 把早期半成品的Bean放入到singletonFactories中。getEarlyBeanReference()方法会在getObject后才会调用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 2.属性填充,也有后置处理器处理和解决循环依赖问题
populateBean(beanName, mbd, instanceWrapper);
// 3.初始化Bean,会对Bean进行Aware、初始化调用和后置处理器处理,这里如果需要AOP会进行AOP
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<>(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.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
createBeanInstance()
会通过反射创建对象。这里也有后置处理器处理,后置处理器作用是判断用哪一个构造器来创建Bean,比如AutowiredAnnotationBeanPostProcessor
。applyMergedBeanDefinitionPostProcessors
这个方法的后置处理器AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor
会把加了@Autowired、@Resource等注解的属性和方法缓存到injectionMetadataCache
中,后面进行属性填充会自动装配。addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
中,会把半成品的Bean放入到singletonFactories,为了解决循环依赖问题。populateBean
Bean属性填充,会把之前缓存的injectionMetadataCache
的信息进行自动转配。initializeBean()
Bean初始化,里面主要执行各种Aware
接口方法,执行InitializingBean.afterPropertiesSet()
方法和AOP。AOP是通过后置处理器执行postProcessAfterInitialization()
方法进行的。
以上就是doCreateBean()
的几个重要的流程。最后Bean初始化后,就是成品Bean了。此时Bean会被返回,通过addSingleton()
方法把成品Bean放入Spring容器中,并且移除earlySingletonObjects
和singletonFactories
(缓存作用,以后不需要用到,所以移除释放内存)。
总结
今天介绍Spring Bean
生命周期部分重要的源码,如果想深入了解,则可以从以上代码着手。
在Spring Bean
生命周期中,主要分为两个阶段。一是通过ConfigurationClassPostProcessor把.class
解析成BeanDefinition阶段,二是通过BeanDefinition
的信息来创建Spring Bean
。
其中在创建Spring Bean
过程中穿插了各种后置处理器处理,例如通过后置处理器判断使用哪一个构造器来创建Bean,获取注解属性和方法缓存到injectionMetadataCache中,进行AOP处理等。
我们分析了doCreateBean()
方法,其实Spring Bean
生命周期就四个阶段:实例化、属性填充、初始化和销毁,前三个阶段都在此方法中,最后销毁的话会通过DisposableBean.destroy()
销毁Bean。
评论区