我的想写《springboot源码解析》这一系列好久了,可是一直角儿心底的知识积累不足,因此一直没有动笔。 因此想找一些小伙伴一块儿写这一系列,互相纠错交流学习。 若是有小伙伴有兴趣一块儿把这一系列的讲解写完的话,加下我微信:13670426148,咱们一块儿完成,当交流学习。 后期还想写一系列介绍rpc框架的,不过要再过一阵子了,先把springboot的写完java
主要补充讲 refresh
方法,为ioc
容器实例化全部的bean
作一个深刻解析,前面第4节讲了配置类的读取并实例化,那普通bean
的实例化在何时呢?,其中代码设计中的依赖注入是怎么解决的呢?让咱们揭开表面Ioc的面纱。spring
延续上一篇,继续摆上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();
}
复制代码
开始获取全部 beanDefinitionspringboot
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()
方法微信
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,处理方式能够是app
aa
,transformedBeanName(A)
获得的结果为 C
(2) 尝试从缓存中加载单例框架
(3) 从头开始加载单例beanless
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);
}
}
复制代码
单例 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
在第一步的获取不到,缓存中不存在咱们要的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点内容
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);
}
}
}
复制代码
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;
}
});
复制代码
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 篇幅过长,因此单独拎出来说
@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 跟 注入属性这两步分开。
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;
}
复制代码
代码异常处理超级繁琐,有点看不下去了,因此直接看重点便可。
将 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);
}
}
复制代码
上面代码有点复杂,直接看第三点便可, 一、2都是缓存的实现,直接看3.,,有两个步骤 (1)根据解析构造函数 determineConstructorsFromBeanPostProcessors
(2)根据构造函数实例化 bean
咱们必须弄明白一件事情,上面的步骤 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 讲解
接下来这段代码,超过了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织入的处理,此处不展开讲。
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,这样就解决了循环依赖的问题。
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);
}
}
}
复制代码
InstantiationAwareBeanPostProcessor
有几个实现类,分别是
AbractAutoProxyCreater
AutowiredAnnotationBeanPostProcessor
: 负责处理@Value
,@Autowired
CommonAnnotationBeanPostProcessor
: 负责处理 @Resource
注解ImportAwareBeanPostProcessor
ImportAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor
ScriptFactoryPostProcessor
先看 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
的实现有多种形式
从新进入正题了
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
能够注入属性也能够注入方法。
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源码深刻解析》