文章目录
- 前情提要
- 准备工作
- 源码分析
- this()
- refresh()
- finishBeanFactoryInitialization()
- preInstantiateSingletons()
- getBean(beanName)
- doGetBean
- createBean(beanName, mbd, args)
- doCreateBean(beanName, mbdToUse, args)
- initializeBean(beanName, exposedObject, mbd)
- invokeAwareMethods(beanName, bean)
- applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)
- invokeInitMethods(beanName, wrappedBean, mbd)
- applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
- 总结
- 参考资料
前情提要
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;
}