前言
主要补充讲 refresh 方法,为ioc 容器实例化所有的bean做一个深入解析,前面第4节讲了配置类的读取并实例化,那普通bean 的实例化在什么时候呢?,其中代码设计中的依赖注入是怎么解决的呢?让我们揭开表面Ioc的面纱。
refresh总方法
延续上一篇,继续摆上refresh方法代码
public void refresh() throws BeansException, IllegalStateException {
//因为该过程必须是同步的,所以进行加锁处理
synchronized(this.startupShutdownMonitor) {
// 1. 容器刷新前的准备,设置上下文,获取属性,验证必要的属性
this.prepareRefresh();
// 2. 销毁原先的 beanFactory,创建新的bean工厂,
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// 3. 配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器等等
this.prepareBeanFactory(beanFactory);
try {
// 4. 添加一个BeanPostProcessor到bean工厂中,类型为WebApplicationContextServletContextAwareProcessor(this)
// 任意Bean都可以很方便的获取到ServletContext。
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
// 5. 实例化所有剩余的(非懒加载)单例
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
我们重点讲的就是第5步, this.finishBeanFactoryInitialization(beanFactory),实例化所有剩余的(非懒加载)单例。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
//这个方法里的东西呢我们只需关注这一行即可
beanFactory.preInstantiateSingletons();
}
开始获取所有 beanDefinition
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 获取所有的 beanDefinition
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
// 得到 beanDefinition
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);
}
}
}
// 如果不是 FactoryBean,
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 出发回调,暂时不知道是什么,做个mark
for (String beanName : beanNames) {
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() 方法
开始走进 getBean方法中
lass AbastractBeanFactory {
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 1. 别名转换
final String beanName = transformedBeanName(name);
Object bean;
// 2. 检查缓存中是否存在 beanName 对应的 bean
// 2.1
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 + "'");
}
}
// 2.2 从bean 中获取对象,
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 3. 如果缓存中不存在 beanName 对应的 bean,则
else {
// 3.1 如果原型模式下,如果指定beanName 的类正在创建中,则抛出异常,原因看后面解释
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
// containsBeanDefinition : beanDefinitionMap.containsKey(beanName);
// 就是如果 DefaultListableBeanFactory 中不包含,就去查 DefaultListableBeanFactory 的父类,看与没有包含该 beanDefinition
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);
}
// 如果 DefaultListableBeanFactory 中已经存在了 该 beanDefinition
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 3.2 找到 mbd 的依赖的 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 + "'");
}
// 先实例化其依赖bean
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 3.3 如果 beanDefinition 是 单例的bean ,先看单例 bean 实例化过程, 从头到尾加载单例 bean
if (mbd.isSingleton()) {
// 3.3.1 调用 创建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;
}
});
// 3.3.2 得到最终的bean ,因为可能会有 FactoryBean ,我们要的实例其实是他的 factory-method 返回的对象才对
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 如果 beanDefinition 是 原型的bean,
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
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;
}
}
// Check if required type matches the type of the actual bean instance.
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) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
}
步骤大概可以分为:
(1)转换对应的 beanName
因为传入的名字可能是 FactoryBean 的name, 格式为 &xxx, 还有可能是别名alias,处理方式可以是
- 去除 FactoryBean 的修饰符, 也如果是 name = '&aa', 那么就会去除 &, 得到了
aa, - 别名的情况,是取别名指定的最终 beanName, 假设别名A 指向B, 而B指向了C,
transformedBeanName(A)得到的结果为C
(2) 尝试从缓存中加载单例
- spring 会把已经加载了的 bean 存在缓存中,一个 map 格式的内存数据
(3) 从头开始加载单例bean
sharedInstance 已经是bean 的原始形态了, 但是他并不一定使我们最终想要的 bean。 有可能是一个工厂 bean , 但是这里得到的是bean 的初始状态,我们真正需要的是工厂 bean 中定义的, factory-method 方法中返回的 bean, 而getObjectForBeanInstance 就是做这个工作的。
下面分开介绍 “ 尝试从缓存中加载单例” 和 "真正bean 的实例化"
尝试从缓存中加载单例
先 show 代码
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;
// 1. 尝试从缓存中获取 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 + "'");
}
}
// 2. 处理 FactoryBean 的情况, 获取其 factory-method 方法中返回的最终Bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
}
1. 缓存中获取bean 流程
单例 bean 在同一个容器内只会被创建一次,后续再获取 bean 就直接从单例缓存中获取,当然也只是尝试加载,首先尝试从缓存中加载,然后再次尝试从 singletonFactory 中加载.
因为在创建单例 Bean 的时候,会存在依赖注入的情况, 而在创建依赖的时候,为了避免循环依赖, Spring 创建 bean 的原则是不等 bean 创建完成就会将创建 bean 的 ObjectFactory 提早曝光加入到 缓存中, 一旦下一个 Bean 创建时候需要依赖上个 bean, 则直接使用 ObjectFactory
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 如果获取不到 尝试从 earlySingletonObjects 中加载, earlySingletonObjects 里是存放 ObjectFactory 的
// 加锁
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 根据 beanName 获取 ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
// 当Bean ,会放到 earlySingletonObjects
this.earlySingletonObjects.put(beanName, singletonObject);
// 已经获取过的bean 对应的 ObjectFactory,,就会被从 singletonFactories 中 remove 掉
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
这里涉及到几个 map , 分别是 singletonObjects、 singletonFactories、earlySingletonObjects、registerSingletons
- Singletonobjects: 用于保存 beanName 和 创建的 bean 实例之间的关系, beanName --> beanInstance
- singletonFactories : beanName -> 创建bean 的工厂 之间的关系, beanName -> ObjectFactory
- earlySingletonObjects: beanName 和创建 bean 实例之间的关系,与 singletonObjects 不用在于,当一个单例Bean 被放到这里后,那么当bean 还在创建过程中,就可通过 getBean方法获取到了,目的是用来检测循环引用的
- registerSingletons: 保存当前所有已注册的 bean
2. 从头开始加载单例bean
在第一步的获取不到,缓存中不存在我们要的bean 的时候,就要主动去从头开始 bean 的加载过程了
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
// 从头到尾加载单例 bean 开始
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 加锁
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
// 判断是否已经加载过了,肯定是没加载过才必须走下面的加载流程
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 1. 开始加载之前的处理, 把 beanName 加入到 singletonsCurrentlyInCreation 中
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 2. 主要内容还是 singletonFactory这个方法, singletonFactory是一个用来做回调的类
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 3. 加载完之后处理, 移除缓存中对该 beanName 的加载记录
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
}
讲解前面的3点内容
2.1 加载之前的处理
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
// 很简单, singletonsCurrentlyInCreation 这个list是用来存储哪些 bean 正在加载的
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
}
2.2 回调逻辑,真正的内容,加载bean
try {
// 2. 主要内容还是 singletonFactory这个方法, singletonFactory是一个用来做回调的类
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
还记得 getSingleton 被调用时候的调用写法吗?所以真正执行的是 createBean(beanName, mbd, args) 方法
// 3.3 如果 beanDefinition 是 单例的bean ,先看单例 bean 实例化过程, 从头到尾加载单例 bean
if (mbd.isSingleton()) {
// 3.3.1 调用 创建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;
}
});
2.3 加载之后的处理
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
其中最主要的还是第二步的回调方法 createBean
回调方法 createBean
因为 createBean 篇幅过长,所以单独拎出来讲
预备
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
// 处理 overwrite 属性,不展开
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//前置处理器处理逻辑, 超级重要的一个方法,就是这个方法实现我们的aop、事务,bean。 但是这里暂时不展开
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 这里才是重点 doCreateBean
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;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
看到 doCreateBean了,感受到内味了没有, 一般 doxxx 方法才是真正干活的,看完前面的内容,大家应该都累了吧,先来个小插曲, 再进入 doCreateBean 中
循环依赖
循环依赖是指 两个bean 互相依赖对方,最终形成闭环
假设A依赖B,B依赖C,C又依赖A,那么当会造成
(1)实例化A的时候,会去实例化B -> (2)实例化B的时候,会去实例化C -> (3)实例化C的时候,重新实例化A,这样就死循环了,程序永远都不会停止
那什么情况时候会发生依赖呢?
在写 spring 配置文件中,一般可以通过两种方式注入依赖属性,一种是 setter 注入和 构造器注入
先复习一下构造器注入 和 'setter注入'
// --- 构造器注入
<bean name="springController" class="***.SpringController">
<!--(2)创建构造器注入,如果主类有带参的构造方法则需添加此配置-->
<constructor-arg index="0" ref="springDao"></constructor-arg>
<constructor-arg index="1" ref="user"></constructor-arg>
</bean>
<bean name="springDao" class="**.SpringDao"></bean>
<bean name="user" class="**.User"></bean>
// --- setter注入
<bean name="springAction" class="***.SpringController">
<!--(1)依赖注入,配置当前类中相应的属性-->
<property name="springDao" ref="springDao"></property>
</bean>
<bean name="springDao" class="**.SpringDao"></bean>
其中构造器注入方式无法解决循环依赖问题,而 spring 是如何解决循环依赖的呢?
通过setter注入方式生成的 bean 才可以解决循环依赖问题
spring采用的方式是将 实例化bean 跟 注入属性这两步分开。
doCreateBean
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 使用对应的策略创建新的实例, 如:工厂方法、构造函数自动注入、简单初始化
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;
}
}
// 2. 判断是否需要提早曝光,
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");
}
// 如果需要提早曝光(单例模式下解决循环依赖都是需要提早曝光的),就是在这里把
// ObjectFactory 是一个函数式接口,里面唯一的方法是 () -> getEarlyBeanReference(beanName, mbd, bean)
// 把 ObjectFactory 加入到 singletonObjects中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//3. 注入属性,其中可能存在依赖与其他bean , 则会递归初始化依赖的 bean
populateBean(beanName, mbd, instanceWrapper);
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;
}
代码异常处理超级繁琐,有点看不下去了,所以直接看重点即可。
1. 实例化 bean
将 BeanDifinition 转换为 BeanWrapper
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 根据 beanName 反射获取 Class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果 beanDefinition 中存在 factoryMethodName 属性,则会调用instantiateUsingFactoryMethod 根据配置生成bean ,这个不是重点不讨论
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
//resolvedConstructorOrFactoryMethod 是用来判断是否已经解析过,如果该bean 已经解析过则 resolved 为 true
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 如果已经解析过
if (resolved) {
// 这里开始了构造器构造 bean 的过程
// 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
// 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
//2. 如果是已经解析过且无参的构造函数,,
return instantiateBean(beanName, mbd);
}
}
// 3. 如果是没有解析过的bean ,则 构造函数必须先解析,之后再调用autowireConstructor 方法注入
// determineConstructorsFromBeanPostProcessors 是根据 参数解析构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 使用解析好的构造函数 构造bean
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 使用默认的构造函数
return instantiateBean(beanName, mbd);
}
}
上面代码有点复杂,直接看第三点即可, 1、2都是缓存的实现,直接看3.,,有两个步骤
(1)根据解析构造函数 determineConstructorsFromBeanPostProcessors
(2)根据构造函数实例化 bean
1. BeanWrapper
我们必须弄明白一件事情,上面的步骤 doCreateBean 的目的是什么?
看返回值,是 BeanWrapper 类型的结构
BeanWrapper 的实现类是 BeanWrapperImpl ,先看 BeanWrapperImpl 的类图

实现的接口有:
PropertyAccessor: 具备对包装bean 属性的读写能力
ConfigurablePropertyAccessor:配置一些属性,如设置 ConversionService、是否暴露旧值、嵌套注入时属性为 null 是否自动创建。
BeanWrapper: 对 bean 进行封装。
暂时可以认为, BeanWrapperImpl 中包含了对 javaBean 属性的操作。直接看 PropertyAccessor 内部的方法.
public interface PropertyAccessor {
boolean isReadableProperty(String propertyName);
boolean isWritableProperty(String propertyName);
Class<?> getPropertyType(String propertyName) throws BeansException;
TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException;
Object getPropertyValue(String propertyName) throws BeansException;
void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException;
void setPropertyValue(PropertyValue pv) throws BeansException;
void setPropertyValues(Map<?, ?> map) throws BeansException;
void setPropertyValues(PropertyValues pvs) throws BeansException;
void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown)
throws BeansException;
void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid)
throws BeansException;
}
暂时可以认为,提供了对 bean属性的操作。 对 BeanWrapperImpl 有兴趣的可以看下文章:
BeanWrapperImpl 讲解
2. autowireConstructor 构造BeanWrapper
接下来这段代码,超过了150行,建议各位客官先喝口水再看,前方高能
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
// 处理了比如注册解析器、value解析器等等,
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
//如果 getBean 方法调用的时候指定方法参数那么直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
// 如果没有指定参数,则去 spring 容器中获取
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
//获取已缓存解析的构造函数或工厂方法(resolvedConstructorOrFactoryMethod----用于缓存已解析的构造函数或工厂方法)
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
////如果缓存不为空,并且构造参数已经解析缓存了,(constructorArgumentsResolved为包可见,用于表示构造参数状态是否已经解析)
// 显然首次进来,都是为null并且没有被解析的
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果上面没有解析过,显然这里参数就是null了,argsToUse也就还为null Spring下面继续解析
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
//如果缓存的构造器不存在,就说明没有bean进行过解析,需要去关联对应的bean的构造器
if (constructorToUse == null || argsToUse == null) {
// 缓存中找不到构造器就救使用方法参数中传进来的构造器
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// 这里 chosenCtors 肯定是存在的.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
//解析对应的构造参数然后添加到ConstructorArgumentValues中
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
//按照访问方式和数量对构造器进行排序;public>protect>private,在同为public时构造器入参多的排在前面
// 所以排在第一位的,是public的,参数最多的构造器
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
// 1. 构造函数确定
// 遍历所有的构造函数
for (Constructor<?> candidate : candidates) {
// 构造函数的参数
Class<?>[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
// 如果参数个数比最小个数还小,那就继续下一个构造器吧。
if (paramTypes.length < minNrOfArgs) {
continue;
}
// 到了这里就是匹配到了 构造器了
ArgumentsHolder argsHolder;
// 有参数,则根据值构造对应参数类型的参数
if (resolvedValues != null) {
try {
// 略(别问为什么略,问就是,我也看不懂)
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
//根据获取到的参数名和已经查到的构造参数和构造参数类型来创建用户创建构造器用的构造参数数组
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
// 构造函数没有参数的情况
else {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
// 执行这里
// 赋值,最终被使用的也是这几个对象,进行
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
// 最终最终最终最终实例化bean 并放入到 BeanWrapper 中
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
看完了上面的方法,我们缓一缓,其实说到底就是,构造参数的确定, 构造函数的确定,最后是根据实例化策略以及得到的构造函数,构造参数实例化 bean , 代码太长,对象结构太复杂,看起来真是非常痛苦, 但是不理解也没关系,差不多往下看,要抓住重点即可。
instantiate 方法暂时可以认为是根据构造器反射生成类,但是其实不只只是反射,还包含了aop织入的处理,此处不展开讲。
2. 提前曝光,循环依赖处理
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// ......略
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 此时这个 bean 就是通过构造器生成的bean ,还没进行属性注入的
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
//...... 略
// 开始判断是否需要提前曝光,这个判断就不解释了
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");
}
// 把重点在这里,把 ObjectFactory 添加到 singletonFactory 中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//3. 注入属性,其中可能存在依赖与其他bean , 则会递归初始化依赖的 bean
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
//.....略
}
// 接上面的 getEarlyBeanReference()
// 第三个参数 bean 就是传进来的 "还未进行属性注入的bean"
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
// 这个是一些后置处理器的处理,跟切面有关,这里只是讨论ioc,暂时略
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
可以看出来, 解决循环依赖的做法就是在getBean 的时候提前暴露获取未进行依赖注入的bean的 ObjectFactory 到spring容器中, 而 objectFactory 的getobject() 方法, 最后返回的是 还未进行属性注入的bean 或者 被后置处理器处理了的代理bean, 可能会不太理解, 那就再看这个方法
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
还记得 getBean() 获取 bean的时候那段循环依赖处理时候的逻辑吗,可以往前翻上去看看.
暴露完之后,当注入属性的时候,会先找到该 bean 依赖的实例并先调用 getBean() 方法实例化其bean,而其实获取到的是ObjectFactory.get() 返回的bean。
参考一张图

根据图,总结起来,spring处理循环依赖的解决过程用文字描述:
spring 把 构造器实例化bean 跟 注入依赖 两个步骤分隔开来, 在初始bean(A)属性注入过程要实例化依赖bean(B)的时候,如果依赖bean(B)也依赖了初始bean(A),在创建依赖bean(B)时候的构建初始bean(A)时通过ObjectFactory 提供的实例化方法来中断初始bean(A)的属性填充,使得依赖bean(B)中持有的初始bean(A) 仅仅是刚初始化并没有填充任何属性的初始bean(A),而最终初始bean(A)是会进行属性填充的,所以依赖bean(B)中的初始bean(A)到最后会是一个完整的bean,这样就解决了循环依赖的问题。
3. 属性注入
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
// 注入属性
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
// 实例化操作的后置处理器 InstantiationAwareBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 执行后置处理器的 postProcessAfterInstantiation ,作用直接看方法名就看得出来了
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
// 我自己启动的时候,这里 pvs 的值是null
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 这个为 false.相信,所以下面不走,相信很多人会看书,或者其他文章说走这里进行autowire,但是springboot2.0我debug的时候不走这块地方,所以我直接跳过....,处理 @Autowire跟 @Resource 的地方还在下面
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
// pvs 是一个对象,里面存在的内容为null
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
// 1. 调用InstantiationAwareBeanPostProcessor#postProcessProperties扩展方法,这里处理@Value,@Autowired等注解。
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
}
1. 调用 InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor 有几个实现类,分别是
AbractAutoProxyCreaterAutowiredAnnotationBeanPostProcessor: 负责处理@Value,@AutowiredCommonAnnotationBeanPostProcessor: 负责处理@Resource注解ImportAwareBeanPostProcessorImportAwareBeanPostProcessorInstantiationAwareBeanPostProcessorScriptFactoryPostProcessor
先看 AutowiredAnnotationBeanPostProcessor
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
// 处理 @Autowire 和 @Resource
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
//1. 获取Class中关于属性注入相关注解的元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//2. 完成属性注入操作
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
}
插入个小片段,讲讲注解元数据 InjectionMetadata 的结构
InjectionMetadata:

可以看出来主要有三个内容, targetClass是类本身, injectedElements是类需要注入的 bean, 像我这个类有 4 个
public class InjectionMetadata {
private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
private final Class<?> targetClass;
private final Collection<InjectedElement> injectedElements;
private volatile Set<InjectedElement> checkedElements;
public static abstract class InjectedElement {
// 最主要的
protected final Member member;
protected final boolean isField;
protected final PropertyDescriptor pd;
protected volatile Boolean skip;
}
需要注入的 bean 信息封存在 InjectedElement 中,看一下InjectedElement 的结构, injectedElement 中最主要的是 Member,Member 接口是反射的用法,用来表示“类”中的一个成员(字段或方法)或构造函数。可以表示的有
-
Constructor - 构造器
-
Executable - 可执行的类型,是Constructor和Method的父类
-
Field - 属性
-
Method - 方法
假设我们是以 @Autowire 通过注入属性的方式注入的bean,那么该 Member 的结构为

而 InjectedElement 的实现有多种形式
- AutowiredFieldElement : @Autowired 方式注入属性时候的数据结构
- AutowiredMethodElement: @Autowired 方式注入方法时候的数据结构
- ResourceElement: @Resource 方式注入时候的数据结构
重新进入正题了
- 获取
Class中关于属性注入相关注解的元数据
// 其中有3个参数进来, beanName 为bean的名称, clazz 为bean的类型, pvs是一个PropertyValues中元素个数为0的 PropertyValues
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// 获取bean的缓存key.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// 根据key得到缓存里面的依赖bean元数据.
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
因为是 @AutoWire 注入的,所以此时 InjectedElement 有两种实现分别是:AutowiredFieldElement 和 AutowiredMethodElement,因为@Autowired 可以注入属性也可以注入方法。
2. 开始注入
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
//是否去查找缓存
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
// desc中存了依赖bean的Field 信息
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//创建依赖对象bean 返回其对象值 (重点)
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
// 缓存DependencyDescriptor
registerDependentBeans(beanName, autowiredBeanNames);
// 缓存名称beanName,直接根据名称查找
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName)) {
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
//反射,set依赖bean 完成注入
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
三步,第一是去缓存中找到
@Override
public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (javaUtilOptionalClass == descriptor.getDependencyType()) {
return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
// 直接看 doResolveDependency
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
// descriptor 中存有依赖 Bean 的信息
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
// 依赖 bean 的类型为 type
Class<?> type = descriptor.getDependencyType();
// 获取@Value注解的field, 这个值也可以是 ${***} 格式的, 先跳过,主要讲 @AutoWire 的解析
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
//如果标识@Autowired注解的属性是复合类型,如Array,Collection,Map,
// 从这个方法获取@Autowired里的值
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
//如果标识@Autowired注解的属性是非复合类型,
// 从这个方法获取@Autowired里的值, 重点,,下面讲解
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
//如果没有符合该类型的Bean
if (matchingBeans.isEmpty()) {
// 没有找到,检验 @autowire 的 require 是否为 true
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
//如果符合该类型的Bean有多个, 按照 @Primary、@Order、@PriorityOrder或Spring 指定的顺序选择
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(type, matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
return (instanceCandidate instanceof Class ?
descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
protected Map<String, Object> findAutowireCandidates(
String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
//从IOC容器中获取所有的符合类型的BeanName,存入候选数组
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length);
for (Class<?> autowiringType : this.resolvableDependencies.keySet()) {
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = this.resolvableDependencies.get(autowiringType);
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
for (String candidate : candidateNames) {
// 不能是自身,否则会无限注入
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { // end :里面会调用 getBean() 方法实例化bean ,以 beanName为key, bean 为value,存进result中
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) {
// Consider fallback matches if the first pass failed to find anything...
DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
if (result.isEmpty()) {
// Consider self references as a final pass...
// but in the case of a dependency collection, not the very same bean itself.
for (String candidate : candidateNames) {
if (isSelfReference(beanName, candidate) &&
(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
isAutowireCandidate(candidate, fallbackDescriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
}
}
return result;
}
参考: 图片借鉴
《Spring源码深入解析》