侧边栏壁纸
博主头像
Terry

『LESSON 5』

  • 累计撰写 90 篇文章
  • 累计创建 21 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Spring Bean生命周期

Terry
2021-03-04 / 0 评论 / 0 点赞 / 798 阅读 / 12,409 字 / 正在检测是否收录...

简述

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();
    }
}

知识点

  1. 我们首先注意Spring中的一个类BeanDefinition,他里面是描述了需要转成Bean的类的信息,比如这个类是否单例,Bean的类型,是否懒加载,依赖哪些类,resource,source等信息,具体可以看看BeanDefinition及其父级。源码中会扫描.class文件,把.class文件解析成BeanDefinition
  2. Spring Bean就是由BeanDefinition中的信息创建的,BeanDefinition.classSpring Bean的中间状态。
  3. DefaultListableBeanFactoryBeanFactory的实现类,我们Spring Bean是存在DefaultSingletonBeanRegistry里面的(因为继承关系所以也是存在DefaultListableBeanFactory中)。有几个属性我们需要注意:
    • beanDefinitionMap用来存放bean对应的BeanDefinition
    • beanDefinitionNames用来存放所有bean的name
    • singletonObjects用来存放完整的单例Bean,就是我们经常用到的Spring Bean的缓存
    • earlySingletonObjects早期单例缓存,也是二级缓存,此缓存的单例Bean没有完全初始化,但是已经经过AOP处理(如果有)。也用于处理Spring Bean循环依赖问题
    • singletonFactories单例工厂缓存,三级缓存,用于处理Spring Bean循环依赖问题(主要处理AOP)
  4. AbstractAutowireCapableBeanFactory也是我们需要关注的,BeanDefinition到Spring Bean都是在此类doCreateBean方法中处理。有三个方法需要注意:
    • createBeanInstanceBean创建,通过反射创建Bean,此时的Bean还是个半成品,没有属性注入和初始化。
    • populateBeanBean属性填充。此步骤含有解决循环依赖和属性注入等操作。
    • initializeBeanBean初始化。此步骤中含有调用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();
			}
		}
	}

最重要的三步在代码中注释了,.classBeanDefinition过程中,是由ConfigurationClassPostProcessor解析的。当BeanDefinition都放入beanDefinitionMap托管后,首先会把后置处理器初始化并交给Spring管理,因为以后BeanDefinitionSpring 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,为了解决循环依赖问题。
  • populateBeanBean属性填充,会把之前缓存的injectionMetadataCache的信息进行自动转配。
  • initializeBean()Bean初始化,里面主要执行各种Aware接口方法,执行InitializingBean.afterPropertiesSet()方法和AOP。AOP是通过后置处理器执行postProcessAfterInitialization()方法进行的。
    以上就是doCreateBean()的几个重要的流程。最后Bean初始化后,就是成品Bean了。此时Bean会被返回,通过addSingleton()方法把成品Bean放入Spring容器中,并且移除earlySingletonObjectssingletonFactories(缓存作用,以后不需要用到,所以移除释放内存)。

总结

今天介绍Spring Bean生命周期部分重要的源码,如果想深入了解,则可以从以上代码着手。
Spring Bean生命周期中,主要分为两个阶段。一是通过ConfigurationClassPostProcessor把.class解析成BeanDefinition阶段,二是通过BeanDefinition的信息来创建Spring Bean
其中在创建Spring Bean过程中穿插了各种后置处理器处理,例如通过后置处理器判断使用哪一个构造器来创建Bean,获取注解属性和方法缓存到injectionMetadataCache中,进行AOP处理等。
我们分析了doCreateBean()方法,其实Spring Bean生命周期就四个阶段:实例化、属性填充、初始化和销毁,前三个阶段都在此方法中,最后销毁的话会通过DisposableBean.destroy()销毁Bean。

0

评论区