1. 引言
我们可以通过ApplicationContext
创建IOC
容器,它有很多个子类,下面通过它的子类AnnotationConfigApplicationContext
的创建来分析下IOC
容器是如何创建并进行初始化的。
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(AopConfig.class);
AnnotationConfigApplicationContext
创建的源码如下:
public AnnotationConfigApplicationContext(Class>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
这里refresh()
方法是重点,它的源码是:
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.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
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.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
} catch (BeansException 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();
}
}
}
refresh()
方法中每一行都很重要,我们依次来进行分析。
2. prepareRefresh()
该方法主要是为IOC
容器启动做一些准备工作,设置容器的启动时间,closed
和active
标识。
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// 空方法,留给子类扩展,初始化 placeholder property
initPropertySources();
// 验证一些必须的属性
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
} else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
这里有个可以扩展的点,我们可以通过重写ApplicationContext
来对自定义环境变量验证,要求必须存在某个环境变量时才能启动IOC
容器。具体细节可以参考:https://blog.csdn.net/boling_cavalry/article/details/81474340
3. obtainFreshBeanFactory
obtainFreshBeanFactory()
主要是获取BeanFactory
,在获取BeanFactory
之前会先创建BeanFactory
。
先来看看BeanFactory
是在什么地方创建的,我们回到AnnotationConfigApplicationContext
创建的地方。
public AnnotationConfigApplicationContext(Class>... annotatedClasses) {
this(); // 调用无参的构造
register(annotatedClasses);
refresh();
}
无参构造器默认会隐式地调用父类的无参构造器方法,AnnotationConfigApplicationContext
的父类是GenericApplicationContext
,而BeanFactory
就是在GenericApplicationContext
的构造方法中创建出来的。
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
再回到obtainFreshBeanFactory()
方法,它主要做了3件事情:
- 设置
refreshed
属性,通过AtomicBoolean
的cas
操作控制refresh()
方法只会被调用一次; - 给
beanFactory
设置serializationId
; - 返回
beanFactory
对象,实际类型为DefaultListableBeanFactory
。
4.prepareBeanFactory
prepareBeanFactory(beanFactory)
主要功能是给上一步获取到的beanFactory
进行一些属性的设置。主要设置了以下属性:
-
BeanFactory
的类加载器、支持表达式解析器; - 添加了两个
BeanPostProcessor
:ApplicationContextAwareProcessor
、ApplicationListenerDetector
; - 设置忽略的自动装配接口:
EnvironmentAware
,EmbeddedValueResolverAware
,ResourceLoaderAware
,ApplicationEventPublisherAware
,MessageSourceAware
,ApplicationContextAware
, 在依赖注入的时候忽略这些接口,也就是这些指定的接口不会被注入进去。 - 注册可以解析的自动装配:
BeanFactory
,ResourceLoader
,ApplicationEventPublisher
,ApplicationContext
,这些类可以在任何地方直接注入; - 添加类加载期织入(
LoadTimeWeaver
)的AspectJ
; - 注册一些组件:
environment
、systemProperties
、systemEnvironment
。
在Java 语言中,从织入切面的方式上来看,存在三种织入方式:
编译期织入、类加载期织入和运行期织入
。编译期织入是指在Java编译期,采用特殊的编译器,将切面织入到Java类中;而类加载期织入则指通过特殊的类加载器,在类字节码加载到JVM时,织入切面;运行期织入则是采用CGLib工具或JDK动态代理进行切面的织入。
AspectJ提供了两种切面织入方式,第一种通过特殊编译器,在编译期,将AspectJ语言编写的切面类织入到Java类中,可以通过一个Ant或Maven任务来完成这个操作;第二种方式是类加载期织入,也简称为LTW(Load Time Weaving)。
5. postProcessBeanFactory
postProcessBeanFactory(beanFactory)
是个空方法。子类可以通过重写这个方法,在BeanFactory
创建并预准备完成之后做些扩展工作。该方法在spring-web
下有对其进行重写。
6. invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(beanFactory)
主要用来执行BeanFactoryPostProcessors
,它会将bean
的信息转化成BeanDefinition
。
BeanFactoryPostProcessors
是BeanFacotry
的后置处理器,在BeanFactory
标准初始化之后执行,它是Spring
提供的众多扩展点之一。BeanFacotry
后置处理器有两个接口:BeanFactoryPostProcessor
和BeanDefinitionRegistryPostProcessor
。
invokeBeanFactoryPostProcessors
方法整体流程如下:
先执行`BeanDefinitionRegistryPostProcessor`接口:
1. 获取所有的`BeanDefinitionRegistryPostProcessor`;
2. 看先执行实现了`PriorityOrdered`优先级接口的`BeanDefinitionRegistryPostProcessor`、 `postProcessor.postProcessBeanDefinitionRegistry(registry)`
3. 在执行实现了`Ordered`顺序接口的`BeanDefinitionRegistryPostProcessor`;
`postProcessor.postProcessBeanDefinitionRegistry(registry)`
4. 最后执行没有实现任何优先级或者是顺序接口的`BeanDefinitionRegistryPostProcessors`;
`postProcessor.postProcessBeanDefinitionRegistry(registry)`
再执行`BeanFactoryPostProcessor`的方法
1. 获取所有的`BeanFactoryPostProcessor`
2. 看先执行实现了`PriorityOrdered`优先级接口的`BeanFactoryPostProcessor`、
`postProcessor.postProcessBeanFactory()`
3. 在执行实现了`Ordered`顺序接口的`BeanFactoryPostProcessor`;
`postProcessor.postProcessBeanFactory()`
4. 最后执行没有实现任何优先级或者是顺序接口的`BeanFactoryPostProcessor`;
`postProcessor.postProcessBeanFactory()`
7. registerBeanPostProcessors
registerBeanPostProcessors(beanFactory)
方法用来向beanFactory
注册BeanPostProcessor
(bean的后置处理器),这又是Spring
容器提供的众多扩展点之一。Bean
的后置处理器共有5个接口:
BeanPostProcessor
DestructionAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor
这5个接口中的方法会在IOC
容器启动过程中不同的时机被回调。
和BeanFacotryPostProcessor
类似,BeanPostProcessor
也能够通过实现PriorityOrdered
、Ordered
接口进行排序。
registerBeanPostProcessors(beanFactory)
方法中将BeanFacotryPostProcessor
分成priorityOrderedPostProcessors
、internalPostProcessors
、orderedPostProcessorNames
、nonOrderedPostProcessorNames
4 类,分好类之后再依次添加BeanFactory
中。
priorityOrderedPostProcessor: 实现了`PriorityOrdered`接口的BeanPostProcessor;
orderedPostProcessorNames: 实现了`Ordered`接口的BeanPostProcessor;
nonOrderedPostProcessorNames: 没有实现排序的BeanPostProcessor
internalPostProcessors: MergedBeanDefinitionPostProcessor接口
通过请求beanFactory.addBeanPostProcessor(postProcessor);
方法,向容器中添加bean
的后置处理器。
8. initMessageSource
initMessageSource()
方法是向容器中注册一个MessageSource
组件。MessageSource
主要作用是支持国际化。
initMessageSource()
方法的主要逻辑是:
先看容器中是否有name
为messageSource
的MessageSource
的组件,
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent essageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
}
如果容器中没有MessageSource
组件,则创建出来并注册到beanFactory
中。
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
9. initApplicationEventMulticaster
initApplicationEventMulticaster()
主要对事件派发器(ApplicationEventMulticaster
)进行初始化,即向beanFactory
注册一个事件派发器。它的逻辑很很简单,就是先判断容器中是否有name=applicationEventMulticaster
的bean,没有的话就创建一个再向容器中注册。
10. onRefresh
这个方法默认实现什么都没有做,主要留给子类进行拓展。
11. registerListeners
registerListeners()
将所有的ApplicationListener
进行注册,并进行事件派发。它的主要逻辑:
- 获取所有的
ApplicationListener
; - 将每个监听器添加到事件派发器中;
- 如果存在早期应用事件,则将其发布出去。
12. finishBeanFactoryInitialization
finishBeanFactoryInitialization(beanFactory)
是个重点方法,它会将所有非懒加载的单例对象进行实例化。
在AbstractApplicationContext#finishBeanFactoryInitialization
方法中,它最终会调用DefaultListableBeanFactory#preInstantiateSingletons
方法对剩下的单实例bean进行初始化,我们重点看看此方法。先贴一下源码:
public void preInstantiateSingletons() throws BeansException {
// beanDefinitionNames在refresh()之前创建ApplicationContext的this()方法中进行设值
List beanNames = new ArrayList<>(this.beanDefinitionNames);
// 遍历触发所有非懒加载的单例bean进行初始化
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//单例、非抽象、非懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// bean是否为工厂bean,工厂bean需要加
if (isFactoryBean(beanName)) {
// 通过 &+beanName来获取工厂bean本身,而beanName获取的是FactoryBean创建的对象
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)
((SmartFactoryBean>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
// 获取FactoryBean创建的bean对象
getBean(beanName);
}
}
}
else {
// 普通的单例bean获取对象,实际会进行初始化
getBean(beanName);
}
}
}
// 触发实现了SmartInitializingSingleton接口的afterSingletonsInstantiated方法
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
其中getBean()
方法是重点,我们需要重点关注。getBean()
是定义在AbstractBeanFactory
类中的方法,getBean()
方法最终会调用doGetBean()
方法(Spring中很多类似的风格,真正干活的都放在doXxx方法中)。
在doGetBean
方法中会完成bean
的初始化,其大概逻辑是:先获取缓存中保存的单实例Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存到名为singletonObjects
的map中),如果获取不到就进行Bean的创建流程,而在每个Bean创建的过程中又会触发各种BeanPostProcessor
的执行。
12.1 获取bean-doGetBean
下面来看看doGetBean
的源码:
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// beanName转换,因为传入的参数可以是alias,也可能是FactoryBean的name,所以需要进行转换
final String beanName = transformedBeanName(name);
Object bean;
// 尝试从缓存中获取bean,这里缓存有三级缓存,主要用来解决循环依赖问题
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// 原型模式,如果存在循环依赖,则抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 获取父BeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果当前容器中没有bean的定义信息,就从父容器中获取
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);
}
}
// 如果不仅仅是做类型检查,标记bean的状态已经创建,即将beanName加入alreadyCreated集合中
if (!typeCheckOnly) {
// 这个方法使用了双重检测机制
markBeanAsCreated(beanName);
}
try {
// 如果存在父bean,则同时合并父bean的相关属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查bean是否是抽象的,是的话就抛出异常
checkMergedBeanDefinition(mbd, beanName, args);
// 加载当前bean依赖的bean
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);
}
}
}
// 处理单例bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 实际创建beand的地方
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// 从单例缓存中移除
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// scope==prototype的bean 创建新的实例.
Object prototypeInstance = null;
try {
// 设置正在创建的状态
beforePrototypeCreation(beanName);
// 创建bean
prototypeInstance = createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
// 返回对应的实例
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
// 其他scope的bean
String scopeName = mbd.getScope();
// scope合法性校验
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
} catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 如果对返回 bean 类型有要求,则进行类型检查,并按需做类型转换
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 执行类型转换,转换成期望的类型
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
} catch (TypeMismatchException ex) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
整个方法可以概括为:
1、转换Bean的名称,获取真正的beanName;
2、检查三级缓存中是否含有bean,如果含有则实例化并返回对象,否则继续流程;
3、如果当前beanFactory中不存在需要的bean,则从父容器中获取bean;
4、如果当前bean存在依赖的bean,就遍历初始化依赖的bean对象;
5、根据bean的作用域不同,对bean进行实例化,作用域分为:singleton、prototype和其他;
6、如果requiredType不为空,则做类型校验,如果需要类型和实际类型不一致,则做类型转换;
7、返回bean对象。
12.2 bean的创建--createBean
上面doGetBean
方法中,创建bean
的工作是调用AbstractAutowireCapableBeanFactory#createBean
来完成的,以下是createBean
的源码(省略日志输出和异常处理):
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 根据设置的class属性或className来解析得到Class引用
Class> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 处理lookup-method和replaced-method标签
try {
mbdToUse.prepareMethodOverrides();
}
// 处理InstantiationAwareBeanPostProcessor,让BeanPostProcessor先拦截返回代理对象
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
// 创建bean实例
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
}
该方法虽然叫createBean,但还不是真正创建bean的地方,它主要还是在做一些前期的准备工作,具体创建bean的方法是doCreateBean
。在看doCreateBean
方法之前,会调用resolveBeforeInstantiation()
方法。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// mbd是程序创建的且存在后置处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 获取最终的class引用,如果是工厂方法则获取工厂所创建的实例类型
Class> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 调用实例化前置处理
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 调用初始化后置处理
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
可以看到如果InstantiationAwareBeanPostProcessor
中的实例化前置处理方法的返回值不为空,就会直接请求BeanPostProcessor
接口中的初始化后置处理方法。而如果这个方法的最终返回值bean
不为空,则会跳过后续的doCreateBean
方法执行(因为bean已经创建完成了),从而形式短路。
12.2.1 doCreateBean
从上面的分析,我们知道:createBean
只是在做创建bean之前的准备工作,真正创建bean
的方法是doCreateBean
。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 如果是单例,尝试获取对应的BeanWrapper.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// BeanWrapper为空,即bean未实例化,则创建bean实例
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.
// 应用MergedBeanDefinitionPostProcessor
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 处理merged bean
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) {
// 为避免循环依赖,在bean实例化完成之前,将对应的ObjectFactory添加到singletonFactories属性中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 初始化Bean实例.
Object exposedObject = bean;
try {
// 对bean的属性进行填充,注入属性值
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) {
// 获取单例bean,不允许早期引用
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 获取依赖的bean name
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
// bean在创建完成之后,其依赖的bean一定是被创建了的
// 如果actualDependentBeans不为空,则说明bean依赖的bean没有完成创建,存在循环依赖
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.
// 注册DisposableBean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
doCreateBean
方法概括起来,主要分为以下步骤:
1)、`创建Bean实例`:createBeanInstance(beanName, mbd, args);利用工厂方法或者对象的构造器创建出Bean实例;
2)、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName):调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);
3)、检查是否需要提前曝光,避免循环依赖
4)、`Bean属性赋值`:populateBean(beanName, mbd, instanceWrapper);
赋值之前:
1)、调用InstantiationAwareBeanPostProcessor后置处理器的postProcessAfterInstantiation();
2)、调用InstantiationAwareBeanPostProcessor后置处理器的postProcessPropertyValues();
赋值之后:
3)、应用Bean属性的值,为属性利用setter方法等进行赋值;
applyPropertyValues(beanName, mbd, bw, pvs);
5)、`Bean初始化`:initializeBean(beanName, exposedObject, mbd);
1)、【执行Aware接口方法】invokeAwareMethods(beanName, bean); 执行xxxAware接口的方法BeanNameAware\BeanClassLoaderAware\BeanFactoryAware
2)、【执行后置处理器postProcessBeforeInitialization】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); BeanPostProcessor.postProcessBeforeInitialization();
3)、【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd);
1)、是否是InitializingBean接口的实现;执行接口规定的初始化;
2)、是否自定义初始化方法;
4)、【执行后置处理器postProcessAfterInitialization】applyBeanPostProcessorsAfterInitialization: BeanPostProcessor.postProcessAfterInitialization();
6)、再次验证是否存在循环依赖;
7)、注册 DisposableBean。
13.finishRefresh
finishRefresh()
完成IOC
容器的创建。
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// 初始化一个和生命周期相关的后置处理器LifecycleProcessor,默认从容器中找,没找到就创建一个
initLifecycleProcessor();
// 回调LifecycleProcessor的onRefresh方法
getLifecycleProcessor().onRefresh();
// 发布容器刷新完成事件
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
至此,Spring
的IOC
容器就创建完毕。
写了一天,有点写不动了。先这样吧,后续有精力再进行更新吧。
参考
https://my.oschina.net/wangzhenchao/blog/918237