Spring 非懒加载 Bean 生命周期源码分析

前情提要

Spring 源码太过庞大,加之本人能力有限,故本文只简要分析与 Spring 初始化 (non-lazy-init) Bean 过程有关的代码,其他与之无关的代码皆省略之。

本文基于 Spring 5.1.7.RELEASE

  • pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.quintin</groupId>
    <artifactId>spring-3</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.7.RELEASE</version>
        </dependency>
    </dependencies>
</project>

准备工作

  • AppConfig.java
package com.quintin;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan("com.quintin")
public class AppConfig {

}
  • X
package com.quintin;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;


@Component
public class X implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware{
    @Autowired
    Y y;

    public X() {
        System.out.println("调用 X 构造方法");
    }

    // CommonAnnotationBeanPostProcessor 这个后置处理器执行了 @PostConstruct 注解的方法
    // org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.LifecycleElement.invoke
    @PostConstruct
    public void init() {
        System.out.println("--- X ------------ lifecycle callback ------------ @PostConstruct ------------");
    }

    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("--- BeanClassLoaderAware ------------ classLoader = " + classLoader);
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("--- BeanFactoryAware ------------ beanFactory = " + beanFactory);
    }

    public void setBeanName(String name) {
        System.out.println("--- BeanNameAware ------------ name = " + name);
    }
}

  • Y
package com.quintin;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;


@Component
public class Y implements ApplicationContextAware, InitializingBean {
    ApplicationContext ac;

    public Y() {
        System.out.println("调用 Y 构造方法");
    }

    /**
     *          ApplicationContextAwareProcessor # invokeAwareInterfaces
     *
     * 			if (bean instanceof ApplicationContextAware) {
     * 				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
     *                        }
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.ac = applicationContext;
    }

    public Object getX(){
        return this.ac.getBean("x");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("------------ Y ------------ lifecycle callback ------------ InitializingBean ------------" +
                " " +
                "afterPropertiesSet");
    }
}
  • QuintinBeanFactoryPostProcessor
package com.quintin;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

@Component
public class QuintinBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("BeanFactoryPostProcessor - beanFactory = " + beanFactory);
    }
}

  • QuintinBeanPostProcessor
package com.quintin;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class QuintinBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if("x".equals(beanName)){
            System.out.println("postProcessBeforeInitialization");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if("x".equals(beanName)){
            System.out.println("postProcessAfterInitialization");
        }
        return bean;
    }
}

  • Test
package com.quintin;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {
    public static void main(String[] args) {
        // 初始化 Spring 容器
        // Spring 容器 包括 BeanDefinition Scanner BeanFactoryPostProcessors 等一系列支撑 Spring 容器运行的组件
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println("ac.getBean():"+ac.getBean(X.class));
        System.out.println("ac.getBean().getX():"+ac.getBean("y", Y.class).getX());
    }
}

  • 控制台输出
BeanFactoryPostProcessor - beanFactory = org.springframework.beans.factory.support.DefaultListableBeanFactory@48eff760: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,appConfig,quintinBeanFactoryPostProcessor,quintinBeanPostProcessor,x,y]; root of factory hierarchy
调用 X 构造方法
调用 Y 构造方法
------------ Y ------------ lifecycle callback ------------ InitializingBean ------------ afterPropertiesSet
--- BeanNameAware ------------ name = x
--- BeanClassLoaderAware ------------ classLoader = sun.misc.Launcher$AppClassLoader@58644d46
--- BeanFactoryAware ------------ beanFactory = org.springframework.beans.factory.support.DefaultListableBeanFactory@48eff760: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,appConfig,quintinBeanFactoryPostProcessor,quintinBeanPostProcessor,x,y]; root of factory hierarchy
postProcessBeforeInitialization
--- X ------------ lifecycle callback ------------ @PostConstruct ------------
postProcessAfterInitialization
ac.getBean():com.quintin.X@5bfbf16f
ac.getBean().getX():com.quintin.X@5bfbf16f

源码分析

断点调试

	/**
	 * Create a new AnnotationConfigApplicationContext, deriving bean definitions
	 * from the given annotated classes and automatically refreshing the context.
	 * @param annotatedClasses one or more annotated classes,
	 * e.g. {@link Configuration @Configuration} classes
	 */
	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//调用父类无参构造,初始化 DefaultListableBeanFactory
		//初始化 reader 和 scanner
		this();
		//注册配置类
		register(annotatedClasses);
		//初始化入口
		refresh();
	}

this()

	/**
	 * Create a new AnnotationConfigApplicationContext that needs to be populated
	 * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
	 */
	public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
  • 调用父类构造方法
	public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

	private final DefaultListableBeanFactory beanFactory;

	@Nullable
	private ResourceLoader resourceLoader;

	private boolean customClassLoader = false;

	private final AtomicBoolean refreshed = new AtomicBoolean();


	/**
	 * Create a new GenericApplicationContext.
	 * @see #registerBeanDefinition
	 * @see #refresh
	 */
	public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}
	
	//...
	
	}

refresh()

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			//完成一些基础的准备工作,例如设置时间、设置启动关闭标志、检查环境变量、并提供子类扩展,用来将属性注入到 ApplicationContext 中、设置事件监听器集合
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			// 为BeanFactory配置容器特性,例如类加载器、事件处理器
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 当前版本是个空的方法,可能后续版本会进行扩展
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 扫描 Bean -> BeanDefinition 然后put到beanDefinitionMap中
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 为BeanFactory注册Post事件处理器
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 初始化信息源,和国际化相关
				initMessageSource();

				// Initialize event multicaster for this context.
				// 初始化容器事件传播器
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 调用子类的某些特殊Bean的初始化方法
				onRefresh();

				// Check for listener beans and register them.
				// 为事件传播器注册事件监听器
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// 初始化所有剩余的单例Bean
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				// 初始化容器的生命周期事件处理器,并发布容器的生命周期事件
				finishRefresh();
			}

			catch (BeansException ex) {
				//...

				// Destroy already created singletons to avoid dangling resources.
				// 销毁已经创建的Bean
				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();
			}
		}
	}

finishBeanFactoryInitialization()

本文主要分析这个方法。

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// ...
		
		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}

preInstantiateSingletons()

	@Override
	public void preInstantiateSingletons() throws BeansException {
		// ...
		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					// ...
				}
				else {
					// 进到这个方法中去
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		// ...
	}

getBean(beanName)

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

doGetBean

do 开头的方法是真正干活的方法

	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.
		// 第一次 getSingleton
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			// ...
			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 (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}
			try {
				// ...
			
				// Create bean instance.
				if (mbd.isSingleton()) {
					// 第二次 getSingleton
					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);
				}

				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					// ...
				}

				else {
				
					// ...
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		// ...
		return (T) bean;
	}

createBean(beanName, mbd, args)

	/**
	 * Central method of this class: creates a bean instance,
	 * populates the bean instance, applies post-processors, etc.
	 * @see #doCreateBean
	 */
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// ...

		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		
		// ...
	}

doCreateBean(beanName, mbdToUse, args)

	/**
	 * Actually create the specified bean. Pre-creation processing has already happened
	 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
	 * <p>Differentiates between default bean instantiation, use of a
	 * factory method, and autowiring a constructor.
	 * @param beanName the name of the bean
	 * @param mbd the merged bean definition for the bean
	 * @param args explicit arguments to use for constructor or factory method invocation
	 * @return a new instance of the bean
	 * @throws BeanCreationException if the bean could not be created
	 * @see #instantiateBean
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 */
	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) {
			//调用构造方法,进行 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 {
					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 初始化
			// AOP 也是在这一步完成
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			// ...
		}

		// ...
		return exposedObject;
	}

initializeBean(beanName, exposedObject, mbd)

  • Lifecycle Callback
    在这里插入图片描述
    实现 InitializingBean 接口和使用 @PostConstruct 注解都会执行生命周期回调方法,但是原理不同。

  • 使用 @PostConstruct 注解的 lifecycle callback

    • applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)
  • 实现 InitializingBean 接口的 lifecycle callback

    • invokeInitMethods(beanName, wrappedBean, mbd)
	/**
	 * Initialize the given bean instance, applying factory callbacks
	 * as well as init methods and bean post processors.
	 * <p>Called from {@link #createBean} for traditionally defined beans,
	 * and from {@link #initializeBean} for existing bean instances.
	 * @param beanName the bean name in the factory (for debugging purposes)
	 * @param bean the new bean instance we may need to initialize
	 * @param mbd the bean definition that the bean was created with
	 * (can also be {@code null}, if given an existing bean instance)
	 * @return the initialized bean instance (potentially wrapped)
	 * @see BeanNameAware
	 * @see BeanClassLoaderAware
	 * @see BeanFactoryAware
	 * @see #applyBeanPostProcessorsBeforeInitialization
	 * @see #invokeInitMethods
	 * @see #applyBeanPostProcessorsAfterInitialization
	 */
	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			//处理Aware接口
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
		   //调用 直接实现 BeanPostProcessor 的类的 postProcessBeforeInitialization 方法
		   //直接实现 BeanPostProcessor 的类只参与了 bean 的初始化过程,间接实现 BeanPostProcessor 的类参与了 bean 的整个实例化过程
		   // 调用 @PostConstruct 注解实现的 lifecycle callback 方法
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//执行 Bean 的生命周期回调中的 init 方法
			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 的类的 PostProcessorsAfterInitialization 方法
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

invokeAwareMethods(beanName, bean)

	private void invokeAwareMethods(final String beanName, final 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);
			}
		}
	}

applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)

	@Override
	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	

invokeInitMethods(beanName, wrappedBean, mbd)

	/**
	 * Give a bean a chance to react now all its properties are set,
	 * and a chance to know about its owning bean factory (this object).
	 * This means checking whether the bean implements InitializingBean or defines
	 * a custom init method, and invoking the necessary callback(s) if it does.
	 * @param beanName the bean name in the factory (for debugging purposes)
	 * @param bean the new bean instance we may need to initialize
	 * @param mbd the merged bean definition that the bean was created with
	 * (can also be {@code null}, if given an existing bean instance)
	 * @throws Throwable if thrown by init methods or by the invocation process
	 * @see #invokeCustomInitMethod
	 */
	protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {

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

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

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)

	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

总结

在这里插入图片描述

参考资料

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值