Spring源码解析之Bean的生命周期

网友投稿 232 2023-01-01

Spring源码解析之Bean的生命周期

一、Bean的实例化概述

前一篇分析了BeanDefinition的封装过程,最终将beanName与BeanDefinition以一对一映射关系放到beanDefinitionMap容器中,这一篇重点分析如何利用bean的定义信息BeanDefinition实例化bean。

二、流程概览

其实bean的实例化过程比较复杂,中间细节很多,为了抓住重点,先将核心流程梳理出来,主要包含以下几个流程:

step1: 通过反射创建实例;

step2:给实例属性赋初始值;

step3:如果Bean类实现BeanNameAware接口,则将通过传递Bean的名称来调用setBeanName()方法;如果Bean类实现BeanClassLoaderAware接口,则将通过传递加载此Bean的ClassLoader对象的实例来调用setBeanClassLoader()方法;如果Bean类实现BeanFactoryAware接口,则将通过传递BeanFactory对象的实例来调用setBeanFactory()方法;

step4: 如果有类实现BeanPostProcessors接口,则将在初始化之前调用postProcessBeforeInitialization()方法;

step5:如果Bean类实现了InitializingBean接口,将调用afterPropertiesSet()方法,如果配置文件中的Bean定义包含init-method属性,则该属性的值将解析为Bean类中的方法名称,并将调用该方法;

step6: 如果有类实现BeanPostProcessors接口,则将在初始化之后调用postProcessAfterInitialization()方法;

step7:如果Bean类实现DisposableBean接口,则当Application不再需要Bean引用时,将调用destroy()方法;如果配置文件中的Bean定义包含destroy-method属性,那么将调用Bean类中的相应方法定义。

三、源码分析

进入AbstractApplicationContext中的fresh()方法,找到finishBeanFactoryInitialization(beanFactory)方法,该类是bean的实例化的入口,具体的实例化由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.

//xml解析时,把所有beanName都缓存到beanDefinitionNames了

List beanNames = new ArrayList<>(this.beanDefinitionNames);

// Trigger initialization of all non-lazy singleton beans...

for (String beanName : beanNames) {

//把父BeanDefinition里面的属性拿到子BeanDefinition中

RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

//如果不是抽象的,单例的,非懒加载的就实例化

if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

//判断bean是否实现了FactoryBean接口

if (isFactoryBean(beanName)) {

Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);

if (bean instanceof FactoryBean) {

FactoryBean> factory = (FactoryBean>) bean;

boolean isEagerInit;

if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {

isEagerInit = AccessController.doPrivileged(

(PrivilegedAction) ((SmartFactoryBean>) factory)::isEagerInit,

getAccessControlContext());

}

else {

isEagerInit = (factory instanceof SmartFactoryBean &&

((SmartFactoryBean>) factory).isEagerInit());

}

if (isEagerInit) {

getBean(beanName);

}

}

}

else {

// 实例化过程

getBean(beanName);

}

}

}

上述代码主要看getBean方法,随后进入doGetBean方法:

protected T doGetBean(

String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)

throws BeansException {

String beanName = transformedBeanName(name);

Object bean;

// 从缓存中获取bean.

Object sharedInstance = getSingleton(beanName);

if (sharedInstance != null &&amhbAjhUJp; 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 {

// Fail if we're already creating this bean instance:

// We're assumably within a circular reference.

if (isPrototypeCurrentlyInCreation(beanName)) {

throw new BeanCurrentlyInCreationException(beanName);

}

// Check if bean definition exists in this factory.

BeanFactory parentBeanFactory = getParentBeanFactory();

if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {

// Not found -> check parent.

String nameToLookup = originalBeanName(name);

if (parentBeanFactory instanceof AbstractBeanFactory) {

return ((AbstractBeanFactory) parentBeanFactory).doGetBean(

nameToLookup, requiredType, args, typeCheckOnly);

}

else if (args != null) {

// Delegation to parent with explicit args.

return (T) parentBeanFactory.getBean(nameToLookup, args);

}

else if (requiredType != null) {

// No args -> delegate to standard getBean method.

return parentBeanFactory.getBean(nameToLookup, requiredType);

}

else {

return (T) parentBeanFactory.getBean(nameToLookup);

}

}

if (!typeCheckOnly) {

markBeanAsCreated(beanName);

}

try {

RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

checkMergedBeanDefinition(mbd, beanName, args);

// Guarantee initialization of beans that the current bean depends on.

String[] dependsOn = mbd.getDependsOn();

if (dependsOn != null) {

for (String dep : dependsOn) {

if (isDependent(beanName, dep)) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName,

"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");

}

registerDependentBean(dep, beanName);

try {

getBean(dep);

}

catch (NoSuchBeanDefinitionException ex) {

throw new BeanCreationException(mbd.getResourceDescription(), beanName,

"'" + beanName + "' depends on missing bean '" + dep + "'", ex);

}

}

}

// Create bean instance

// 创建bean实例

if (mbd.isSingleton()) {

sharedInstance = getSingleton(beanName, () -> {

try {

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

}

...

}

由上述代码可知,先从缓存中获取bean,如果没有,则创建bean,最重要的方法就是getSingleton,该方法第二个参数是个函数式接口,进入getSingleton方法,当调用singletonObject = singletonFactory.getObject()时,会触发函数式接口中的createBean方法,随后一路进入doCreateBean,这个方法里面完成了所有实例化所需的步骤:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

throws BeanCreationException {

// Instantiate the bean.

// 真正开始创建bean的实例.

BeanWrapper instanceWrapper = null;

if (mbd.isSingleton()) {

instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);

}

if (instanceWrapper == null) {

instanceWrapper = createBeanInstance(beanName, mbd, args);

}

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 {

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.

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");

}

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

}

// Initialize the bean instance.

Object exposedObject = bean;

try {

// 属性赋值

populateBean(beanName, mbd, instanceWrapper);

// 初始化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 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 " +

"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");

}

}

}

}

// Register bean as disposable.

// 有必要时,注册bean的销毁

try {

registerDisposableBeanIfNecessary(beanName, bean, mbd);

}

catch (BeanDefinitionValidationException ex) {

throw new BeanCreationException(

mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);

}

return exposedObject;

}

从上述源码中看出bean的实例化主要分为以下三步:

step1:bean的创建;

step2:给bean的属性赋值;

step3:bean的初始化;

接着得到exposedObject这个已经完全实例化后的bean返回,其中当有必要时,注册bean的销毁,后面再详细看,先抓住主要流程。其中step3也是比较重要的方法,进入该方法:

protected Object initializeBean(String beanName, Object bean, @NullablhbAjhUJe RootBeanDefinition mbd) {

if (System.getSecurityManager() != null) {

AccessController.doPrivileged((PrivilegedAction) () -> {

invokeAwareMethods(beanName, bean);

return null;

}, getAccessControlContext());

}

else {

// 激活aware接口

invokeAwareMethods(beanName, bean);

}

Object wrappedBean = bean;

if (mbd == null || !mbd.isSynthetic()) {

// 初始化前处理的beanPostProcessor

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

}

try {

// 激活 init-method方法

invokeInitMethods(beanName, wrappedBean, mbd);

}

catch (Throwable ex) {

throw new BeanCreationException(

(mbd != null ? mbd.getResourceDescription() : null),

beanName, "Invocation of init method failed", ex);

}

if (mbd == null || !mbd.isSynthetic()) {

// 初始化后处理的beanPostProcessor

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

}

return wrappedBean;

}

从上面源码可知,梳理出主要的四个步骤:

step1:激活aware接口,完成aware接口的相关操作;

step2:初始化前处理的beanPostProcessor;

step3:完成init-method方法;

step4:初始化后处理的beanPostProcessor;

BeanPostProcessor作用是对初始化后的bean进行增强处理,在该阶段 BeanPostProcessor 会处理当前容器内所有符合条件的实例化后的 bean 对象。它主要是对 Spring 容器提供的 bean 实例对象进行有效的扩展,允许Spring在初始化 bean 阶段对其进行定制化修改,如处理标记接口或者为其提供代理实现。

四、演示

定义一个MyBeanPostProcessor实现BeanPostProcessor接口

public class MyBeanPostProcessor implements BeanPostProcessor {

@Override

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

System.out.println("post Process Before Initialization 被调用...");

return bean;

}

@Override

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

System.out.println("post Process after Initialization 被调用...");

return bean;

}

}

定义一个LifeCycleBean类,实现如下接口:

public class LifeCycleBean implements BeanNameAware, BeanFactoryAware, BeanClassLoaderAware,

InitializingBean, DisposableBean {

private String property;

public String getProperty() {

return property;

}

public void setProperty(String property) {

System.out.println("属性注入....");

this.property = property;

}

public LifeCycleBean(){

System.out.println("构造函数调用...");

}

@Override

public void setBeanClassLoader(ClassLoader classLoader) {

System.out.println("BeanClassLoaderAware 被调用...");

}

@Override

public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

System.out.println("BeanFactoryAware 被调用...");

}

@Override

public void setBeanName(String name) {

System.out.println("BeanNameAware 被调用...");

}

@Override

public void destroy() throws Exception {

System.out.println("DisposableBean destroy 被调用...");

}

@Override

public void afterPropertiesSet() throws Exception {

System.out.println("InitializingBean afterPropertiesSet 被调用...");

}

public void initMethod(){

System.out.println("init-method 被调用...");

}

public void destroyMethod(){

System.out.println("destroy-method 被调用...");

}

public void display(){

System.out.println("方法调用...");

}

}

指定配置文件spring.xml,配置init-method与destroy-method方法

init-method="initMethod" destroy-method="destroyMethod">

init-method="initMethod" destroy-method="destroyMethod">

测试类如下:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = {"classpath:spring.xml"})

public class TestSpring {

@Test

public void testLifeCycleBean() {

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

}

执行结果:

构造函数调用...

属性注入....

BeanNameAware 被调用...

BeanClassLoaderAware 被调用...

BeanFactoryAware 被调用...

post Process Before Initialization 被调用...

InitializingBean afterPropertiesSet 被调用...

init-method 被调用...

post Process after Initialization 被调用...

DisposableBean destroy 被调用...

destroy-method 被调用...

五、总结

本篇从一个初学者的角度概览了bean的整个生命周期,并描述了其中的主要流程,阅读源码的初始阶段,优先抓住主要流程,别陷入细节,并通过跑案例、写注解、画流程图等方式加深理解,后续将继续分析bean实例化中的核心流程、设计思想等。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:圆通国际快递物流查询单号(圆通国际快递物流查询单号官网)
下一篇:网站api接口采集(官方采集接口)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~