什么是DI?
DI(Dependency Injection)依赖注入:当对象内包含对其他对象的引用时,Spring会帮我们创建或定义这些依赖对象,而无需知道依赖对象的位置甚至具体实现类,实现更有效的解耦。
既然已经知道什么是依赖注入,那么按照探究问题的准则,首先我们会想:依赖注入是什么时候开始的?又是怎么注入的?同时简单考虑下如果是自己会大概怎么去实现(不考虑细节)。比如我们知道IOC容器中保存了Bean对象,那么一个对象的属性依赖对象能不能直接从容器中拿然后赋值?根据容器中保存的beanName去拿?或者如果容器中没有,是不是要另外创建然后引用赋值过来?这样的话,是不是得先判断这个属性是不是Bean对象?还有如果新创建的对象中又有属性依赖其他对象怎么办?递归?等等。
不要觉得自己好像啥也想不出来或者肯定不对不敢随意猜,带着疑问去探究才会得到实际的印证,加深对本质的了解,而且你会更容易看的下去源码,所谓念念不忘,必有回响。
准备工作
接下来,我们先做一些准备工作,主要还是为了“眼熟”,提前熟悉一些解析源码时需要用到的知识点。
第一步:注入时机
也就是依赖注入是什么时候开始的?前一篇我们解析了Spring的IOC初始化流程,我们知道主要的流程在refresh()方法里面实现的,而解析加载注册主要发生在方法内的obtainFreshBeanFactory()中实现的,之后的代码中我们注意到finishBeanFactoryInitialization(beanFactory)这个方法,这个方法就是初始化所有剩余的单例Bean,点进去最后发现调用的是DefaultListableBeanFactory类中的preInstantiateSingletons()方法,我们看下源码,
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
List beanNames = new ArrayList<>(this.beanDefinitionNames);
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//Bean满足非抽象类,单例,lazy-init属性为false
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean> factory = (FactoryBean>) getBean(FACTORY_BEAN_PREFIX + beanName);
//是否预实例化
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction) () ->
((SmartFactoryBean>) factory).isEagerInit(),
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
//调用getBean方法,触发容器对Bean实例化和依赖注入过程
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
这个方法是对配置lazy-init属性等于fasle的单例Bean的预实例化,我们看到到最后都调用了getBean()方法,它就是对Bean实例化和依赖注入过程,而具体更深入的探究我们后面会慢慢展开。
所以综上所述,我们知道了在IOC的初始化中其实包含了依赖注入的过程,同时通过对getBean()的延伸,进一步得到了第一个问题的答案,依赖注入的时机:
- 非延迟加载的Bean: IOC初始化中对进行预实例化(也是调用getBean()方法)。
- 延迟加载的Bean: 第一次调用getBean()方法时。
第二步:注入策略
Spring中注入策略有两种:
- 有参构造方法注入: 带有参数的构造函数来完成实例化或者带参数的static工厂方法,因为需要对参数进行解析转换,所以过程复杂。
- 无参构造方法注入: 默认实例化方法,例如使用setter方法注入,通过无参数构造函数或无参数的static工厂方法,过程简单。
第三步:自动装配方式
Spring官网中已经有详细的介绍,关于自动装配的方式有四种:
- no:默认没有自动装配,必须由ref配置Bean的引用。
- byName:根据属性名称在IOC容器中查找Bean,然后通过setter方法来注入属性(前提是必须有)。
- byType:根据属性类型在IOC容器中查找Bean,只存在一个才会注入,多个会引发异常,没有则不注入。
- constructor:根据构造函数的参数类型在IOC容器中查找Bean,没有则引发异常。
但是自动装配也有一些局限性和缺点,比如不能装配简单属性、不如显示装配准确、多个Bean会引发异常等,这些都在官方文档中有更详细的介绍。
第四步:关键类和属性
-
缓存的属性:后面我们解析源码的时候会经常看到一些存储Bean的不同的数据结构,Map或Set,我们先熟悉下它们的用处:
- Map
singletonObjects:保存beanName和Bean实例之间的关系。 - Map
> singletonFactories:保存beanName和Bean工厂之间的关系。 - Map
earlySingletonObjects:保存beanName和Bean实例之间的关系,和singletonObjects不同的是,一个单例Bean还未创建完成前就被存放进去,且能通过getBean()方法拿到,主要目的是用于检查循环依赖。 - Set
registeredSingletons:保存当前所有已注册的Bean的beanName。 - Set
singletonsCurrentlyInCreation:保存当前正在创建中的Bean的beanName。
- Map
-
FactoryBean:看到这个类,我们很容易想到BeanFactory,其实他两没有关系,IOC中我们已经了解BeanFactory是一个工厂的顶层接口,定义了IOC容器的基本行为,获取bean及bean的各种属性。而FactoryBean是一个工厂Bean接口,目的是用来隐藏复杂Bean的实例化细节,子类通过定制来实现实例化的逻辑,用来产生其他Bean实例。看下它的源码结构
其中getObject()方法会返回创建的Bean实例;getObjectType()返回创建的Bean类型;isSingleton()返回创建的Bean实例的作用域是否是单例,如果返回true,该Bean实例就会放到单例的缓存池中。
BeanWrapper:类似BeanDefinition一样,都对Bean的一种封装,但是它对Bean执行了一些操作,例如设置和检索属性。源码中实际使用的是它的实现类BeanWrapperImpl。
依赖注入流程
前面我们已经做了一些简单的了解,这也是为接下来解析源码过程而做的铺垫。开始前,我们先回忆下刚开头我们自己提的一些疑问(具体可以到上面再看下),接下来我们会带着这些疑问去探究。
从无到有,那么我们还是要从入口开始,前面我们知道了依赖注入的入口就是从调用getBean()方法开始,看着很眼熟,再想想之前IOC中讲的BeanFactory顶级工厂不就是做这个事的吗,回顾它的源码发现,果然是它。我们知道它是一个顶层接口,实现肯定是在它的子类中。顺着准备工作中介绍的DefaultListableBeanFactory类中的preInstantiateSingletons()方法中调用的getBean()方法,点进去我们发现实际调用的是AbstractBeanFactory的getBean()方法。
万事开头难,既然现在入口已经找到了,接下来的事就“简单”了。
首先点进去看源码,
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//转换为真正的beanName
final String beanName = transformedBeanName(name);
Object bean;
// 先从缓存中获取Bean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
//是否是正在创建的单例Bean
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//获取真正需要的Bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//是否是正在创建的原型Bean
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//获取父容器
BeanFactory parentBeanFactory = getParentBeanFactory();
//父级容器不存在,且容器中不存在beanName的Bean
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//获取原始beanName
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 递归调用
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
//到父容器中查找符合beanName和参数的Bean
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
//到父容器中查找符合beanName和类型的Bean
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//Bean是否需要类型验证
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//RootBeanDefinition转换,合并父类的属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//获取Bean所有依赖Bean的beanName
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 + "'");
}
//注册缓存依赖的beanName
registerDependentBean(dep, beanName);
//递归调用
getBean(dep);
}
}
//创建单例Bean对象
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
//创建Bean实例
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//清除Bean实例
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//创建原型Bean对象
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
//创建前回调,默认实现将beanName注册为当前正在创建的原型Bean
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//创建后回调,默认实现移除刚注册的原型Bean的beanName
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//创建的非单例、非原型的Bean
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;
}
}
//类型转换
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.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
从源码中看到,具体的实现都是在doGetBean()方法中,这里实现了从IOC容器中获取Bean以及触发依赖注入。乍一看,代码相当长,做了很多的处理和实现(是不是很晕),但不要慌,我们细水长流,一步一步往下看。通过上面代码注释我们大概知道了实现的逻辑以及大概的流程,下面我们梳理罗列下:
1.转换真正的beanName
为什么传入的beanName不能直接使用呢?因为这里传入的可能是别名(Alias),也可能是FactoryBean的beanName,所以需要转换,点进去可以看到怎么处理的,处理比较简单,这里就不贴源码了,简单说下,感兴趣的话可以点进去看看。
- 首先如果是FactoryBean的话,去除特定&的修饰符,比如把&name变成name;
- 拿到别名指向的最终beanName,比如别名A->别名B,别名B->别名C,最后返回的就是C。
2.从缓存中获取Bean
我们知道Spring的单例只会被创建一次,然后放在IOC容器中,之前我们是不是想过Bean能不能先从容器中拿?看来Spring确实做了这样的处理,这里缓存获取其实分成了两步:
-
第一步:首先会调用getSingleton()方法,尝试从当前容器的缓存中去加载,如果能拿到,我们会直接执行第5步,也就是调用getObjectForBeanInstance()方法获取真正需要的Bean,这个方法的实现后面会详细解析;我们先看getSingleton()的源码实现,
@Override @Nullable public Object getSingleton(String beanName) { return getSingleton(beanName, true); } @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { ObjectFactory> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }
首先会从singletonObjects中查找beanName对应的Bean对象,有就直接返回,没有的话同时当前beanName对应的Bean对象不是正在创建的单例,则从earlySingletonObjects中查找,如果还没有则再去singletonFactories中找对应的ObjectFactory,通过其getObject()方法获取Bean对象,同时将beanName和Bean对象缓存到earlySingletonObjects,并从singletonFactories移除beanName和ObjectFactory的对应关系。前面准备工作的关键属性中我们已经知道了这几个属性所代表的含义,但是可能有一些疑问,ObjectFactory有什么用?
ObjectFactory:从名字能猜到是一个对象工厂接口,通过它可以返回对象的实例,实际也是这样;是不是感觉类似于FactoryBean,都是通过getObject()返回对象实例,但是ObjectFactory基于SPI机制(服务发现机制),它的实现类作为 API 提供给其他 bean(通过注入)。它们其实相当于BeanFactory的封装,实现类的getObject()最后调用的还是BeanFactory的getBean()方法去实例化对象。
和beanName的关系是什么时候保存的?
缓存的时间:Spring中为了避免循环依赖,在创建Bean的时候不等Bean创建完成就讲ObjectFactory提前存放到缓存中去,后面的Bean创建是需要依赖这个Bean,就能直接使用ObjectFactory。(循环依赖的处理在依赖注入中很常见,下一篇会单独解析)
同时我们看到这里通过synchronized关键字来保证证线程安全(想想之前IOC的初始化,不难发现,Spring对于Bean的频繁创建的一些相关信息缓存都通过synchronized来保证线程安全,确保容器内数据的一致性,后面我们也能经常看到)
-
第二步:第一步缓存没有拿到Bean的话,就会再从当前容器的存在的父容器的缓存中去加载,看下源码,
// 判断循环依赖 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { //转换beanName String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { //根据名称和显式的参数查找 return (T) parentBeanFactory.getBean(nameToLookup, args); } else { //根据名称和类型查找 return parentBeanFactory.getBean(nameToLookup, requiredType); } }
我们看到会根据两种方式去查找:beanName和参数、beanName和类型,其实就是递归调用getBean()方法。不过查找前,需要判断如果当前beanName对应的Bean是正在创建的原型Bean,则会抛出循环依赖异常。
3.对依赖的Bean先进行初始化
先转换获得RootBeanDefinition,同时合并父类的属性;然后判断当前Bean内是否有依赖的Bean,如果有则如下遍历处理:
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}
public void registerDependentBean(String beanName, String dependentBeanName) {
//beanName转换
String canonicalName = canonicalName(beanName);
Set dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
return;
}
// 保证证线程安全,缓存到dependentBeanMap
synchronized (this.dependentBeanMap) {
dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
dependentBeans = new LinkedHashSet<>(8);
this.dependentBeanMap.put(canonicalName, dependentBeans);
}
dependentBeans.add(dependentBeanName);
}
// 保证证线程安全,缓存到dependenciesForBeanMap
synchronized (this.dependenciesForBeanMap) {
Set dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
if (dependenciesForBean == null) {
dependenciesForBean = new LinkedHashSet<>(8);
this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
}
dependenciesForBean.add(canonicalName);
}
}
- Bean和依赖的Bean互相缓存beanName:注册依赖的beanName到缓存Map
> dependentBeanMap(beanName-->依赖Bean的beanName的集合)中去,同时也将当前beanName注册到缓存Map > dependenciesForBeanMap(beanName --> 被依赖Bean的beanName)中去。 - 创建初始化:递归调用getBean()先创建依赖的Bean并初始化。
4.根据不同Scope的Bean进行实例化(重点)
我们知道Spring有存在不同的作用域,默认是单例而已;这里需要根据Scope来选择不同的实例化策略,比如prototype、request、session、application等。他们都是通过调用createBean()方法来完成创建Bean对象实例的,它是Bean注入的重点,后面主要也是围绕这个方法来深入解析。
解析createBean()源码之前,细心的小伙伴可能发现,除了单例Bean之外,prototype以及其他作用域的实例化,在调用createBean()的前后,分别回调了beforePrototypeCreation()、afterPrototypeCreation()方法,那它们是做什么的呢?回想一下我们之前从缓存中尝试加载Bean的时候是不是判断过isSingletonCurrentlyInCreation()、isPrototypeCurrentlyInCreation()这两个方法,前面是判断单例的,后面是原型的,而原型判断的来源就是这两个回调方法,我们再看下它们的源码,
protected void beforePrototypeCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
if (curVal == null) {
this.prototypesCurrentlyInCreation.set(beanName);
}
else if (curVal instanceof String) {
Set beanNameSet = new HashSet<>(2);
beanNameSet.add((String) curVal);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);
}
else {
Set beanNameSet = (Set) curVal;
beanNameSet.add(beanName);
}
}
protected void afterPrototypeCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
if (curVal instanceof String) {
this.prototypesCurrentlyInCreation.remove();
}
else if (curVal instanceof Set) {
Set beanNameSet = (Set) curVal;
beanNameSet.remove(beanName);
if (beanNameSet.isEmpty()) {
this.prototypesCurrentlyInCreation.remove();
}
}
}
实现很容易理解,就是创建前把创建的Bean的beanName放到prototypesCurrentlyInCreation缓存中,创建完成后再去缓存中删除。但这里的实现代码你是不是有点感觉不太的地方?之前我们讲过Spring对于Bean的频繁创建的缓存都通过synchronized来保证线程安全,确保容器内数据的一致性,这里没有加锁,难道不会产生线程安全的问题吗?!没错,这里肯定也要保住线程安全,查看prototypesCurrentlyInCreation的属性,我们才发现原来它是ThreadLocal
讲完这个小前奏,那我们开始解析createBean()的源码了。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 解析Class
Class> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
// 标记Bean中的方法是否重载
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//解析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 {
//创建Bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException ex) {
throw ex;
}
catch (ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
通过上面代码,能看到创建Bean前做了一些准备:
- resolveBeanClass():根据Bean的Class属性和beanName解析Class,没有则通过类加载器将beanName名称解析为类引用存放到BeanDefinition中用于后续使用;
- prepareMethodOverrides():判断Bean中的方法是否重载,如果不重载就将MethodOverride的overloaded属性标记为false,以避免参数类型检查的开销,主要后面在AOP代理中会用到;
- resolveBeforeInstantiation():这其实是一个短路判断,如果Bean配置了前后处理器,并且调用applyBeanPostProcessorsBeforeInstantiation()返回的对象不为空(实质是调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()方法返回经过处理的代理Bean),则会调用applyBeanPostProcessorsAfterInitialization方法直接完成初始化,不需要进行常规的Bean创建流程。
而我们需要关注的具体实现其实是在doCreateBean()方法中,
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建Bean对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 调用后置处理器,合并Bean的定义
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//提前缓存Bean
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
//属性注入
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean对象
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
// 在缓存中加载Bean
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
// 已注册的Bean等于正在实例化的Bean,则初始化完成
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 检查当前Bean依赖的其他Bean如果还未被创建,则抛出循环依赖异常
String[] dependentBeans = getDependentBeans(beanName);
Set 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.");
}
}
}
}
try {
// 注册Bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
通过这段源码,我们也比较清晰的看到了以下几个实现流程:
4.1.实例化Bean
首先,调用了createBeanInstance()方法,并且从返回值看到返回的是Bean创建后封装成的BeanWrapper对象,
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//解析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) {
//自定义Supplier实例化
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
//工厂方法实例化
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
//有参构造方法实例化
return autowireConstructor(beanName, mbd, null, null);
}
else {
//无参构造方法实例化
return instantiateBean(beanName, mbd);
}
}
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//有参构造方法实例化
return autowireConstructor(beanName, mbd, ctors, args);
}
//无参构造方法实例化
return instantiateBean(beanName, mbd);
}
从源码看到,这里Spring提供了四种Bean对象的实例化策略:
-
自定义Supplier实例化:如果你点进去看Supplier源码可能有点蒙,仅仅通过get()去获取一个Bean对象,也没有定义的实现类。
@FunctionalInterface public interface Supplier
{ /** * Gets a result. * * @return a result */ T get(); } 其实很简单,我用AnnotationConfigApplicaitonContext为例写个简单的Demo,就清楚了。
public Class Demo{ public static void main(String args[]){ AnnotationConfigApplicaitonContext ac = new AnnotationConfigApplicaitonContext(); ac.registerBean(User.class, new Supplier
(){ @Override public Person get() { return new Person("哈哈"); } }); Person p = ac.getBean(Person.class); } } public Person{ private String name; public Person(String name){ this.name = name; } } -
工厂方法实例化:先贴一下源码,
protected BeanWrapper instantiateUsingFactoryMethod( String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) { return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs); } public BeanWrapper instantiateUsingFactoryMethod( final String beanName, final RootBeanDefinition mbd, @Nullable final Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw); Object factoryBean; Class> factoryClass; boolean isStatic; String factoryBeanName = mbd.getFactoryBeanName(); if (factoryBeanName != null) { if (factoryBeanName.equals(beanName)) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "factory-bean reference points back to the same bean definition"); } factoryBean = this.beanFactory.getBean(factoryBeanName); if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) { throw new ImplicitlyAppearedSingletonException(); } factoryClass = factoryBean.getClass(); isStatic = false; } else { if (!mbd.hasBeanClass()) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "bean definition declares neither a bean class nor a factory-bean reference"); } factoryBean = null; factoryClass = mbd.getBeanClass(); isStatic = true; } Method factoryMethodToUse = null; ArgumentsHolder argsHolderToUse = null; Object[] argsToUse = null; if (explicitArgs != null) { argsToUse = explicitArgs; } else { Object[] argsToResolve = null; synchronized (mbd.constructorArgumentLock) { factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod; if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) { // Found a cached factory method... argsToUse = mbd.resolvedConstructorArguments; if (argsToUse == null) { argsToResolve = mbd.preparedConstructorArguments; } } } if (argsToResolve != null) { argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve); } } if (factoryMethodToUse == null || argsToUse == null) { // Need to determine the factory method... // Try all methods with this name to see if they match the given arguments. factoryClass = ClassUtils.getUserClass(factoryClass); Method[] rawCandidates = getCandidateMethods(factoryClass, mbd); List
candidateSet = new ArrayList<>(); for (Method candidate : rawCandidates) { if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) { candidateSet.add(candidate); } } Method[] candidates = candidateSet.toArray(new Method[candidateSet.size()]); AutowireUtils.sortFactoryMethods(candidates); ConstructorArgumentValues resolvedValues = null; boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); int minTypeDiffWeight = Integer.MAX_VALUE; Set ambiguousFactoryMethods = null; int minNrOfArgs; if (explicitArgs != null) { minNrOfArgs = explicitArgs.length; } else { // We don't have arguments passed in programmatically, so we need to resolve the // arguments specified in the constructor arguments held in the bean definition. if (mbd.hasConstructorArgumentValues()) { ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } else { minNrOfArgs = 0; } } LinkedList causes = null; for (Method candidate : candidates) { Class>[] paramTypes = candidate.getParameterTypes(); if (paramTypes.length >= minNrOfArgs) { ArgumentsHolder argsHolder; if (explicitArgs != null){ if (paramTypes.length != explicitArgs.length) { continue; } argsHolder = new ArgumentsHolder(explicitArgs); } else { try { String[] paramNames = null; ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer(); if (pnd != null) { paramNames = pnd.getParameterNames(candidate); } argsHolder = createArgumentArray( beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring); } catch (UnsatisfiedDependencyException ex) { if (this.beanFactory.logger.isTraceEnabled()) { this.beanFactory.logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex); } // Swallow and try next overloaded factory method. if (causes == null) { causes = new LinkedList<>(); } causes.add(ex); continue; } } int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); if (typeDiffWeight < minTypeDiffWeight) { factoryMethodToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; ambiguousFactoryMethods = null; } else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight && !mbd.isLenientConstructorResolution() && paramTypes.length == factoryMethodToUse.getParameterCount() && !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) { if (ambiguousFactoryMethods == null) { ambiguousFactoryMethods = new LinkedHashSet<>(); ambiguousFactoryMethods.add(factoryMethodToUse); } ambiguousFactoryMethods.add(candidate); } } } if (factoryMethodToUse == null) { if (causes != null) { UnsatisfiedDependencyException ex = causes.removeLast(); for (Exception cause : causes) { this.beanFactory.onSuppressedException(cause); } throw ex; } List argTypes = new ArrayList<>(minNrOfArgs); if (explicitArgs != null) { for (Object arg : explicitArgs) { argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null"); } } else if (resolvedValues != null){ Set valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount()); valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values()); valueHolders.addAll(resolvedValues.getGenericArgumentValues()); for (ValueHolder value : valueHolders) { String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) : (value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null")); argTypes.add(argType); } } String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes); throw new BeanCreationException(mbd.getResourceDescription(), beanName, "No matching factory method found: " + (mbd.getFactoryBeanName() != null ? "factory bean '" + mbd.getFactoryBeanName() + "'; " : "") + "factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " + "Check that a method with the specified name " + (minNrOfArgs > 0 ? "and arguments " : "") + "exists and that it is " + (isStatic ? "static" : "non-static") + "."); } else if (void.class == factoryMethodToUse.getReturnType()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid factory method '" + mbd.getFactoryMethodName() + "': needs to have a non-void return type!"); } else if (ambiguousFactoryMethods != null) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Ambiguous factory method matches found in bean '" + beanName + "' " + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " + ambiguousFactoryMethods); } if (explicitArgs == null && argsHolderToUse != null) { argsHolderToUse.storeCache(mbd, factoryMethodToUse); } } try { Object beanInstance; if (System.getSecurityManager() != null) { final Object fb = factoryBean; final Method factoryMethod = factoryMethodToUse; final Object[] args = argsToUse; beanInstance = AccessController.doPrivileged((PrivilegedAction 实现逻辑很复杂,其实它和下面的有参构造方法实例化是差不多的。
-
有参构造方法实例化:先看源码,
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd, @Nullable Constructor>[] chosenCtors, @Nullable final Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw); Constructor> constructorToUse = null; ArgumentsHolder argsHolderToUse = null; Object[] argsToUse = null; if (explicitArgs != null) { argsToUse = explicitArgs; } else { //先从缓存中获取构造参数 Object[] argsToResolve = null; synchronized (mbd.constructorArgumentLock) { constructorToUse = (Constructor>) mbd.resolvedConstructorOrFactoryMethod; if (constructorToUse != null && mbd.constructorArgumentsResolved) { argsToUse = mbd.resolvedConstructorArguments; if (argsToUse == null) { argsToResolve = mbd.preparedConstructorArguments; } } } if (argsToResolve != null) { //参数类型解析,比如test(int a,int b)方法,把传入的a、b为String类型转为int argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve); } } //缓存为空 if (constructorToUse == null) { boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); ConstructorArgumentValues resolvedValues = null; int minNrOfArgs; if (explicitArgs != null) { minNrOfArgs = explicitArgs.length; } else { // 解析 ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } 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); } } AutowireUtils.sortConstructors(candidates); int minTypeDiffWeight = Integer.MAX_VALUE; Set
> ambiguousConstructors = null; LinkedList causes = null; for (Constructor> candidate : candidates) { Class>[] paramTypes = candidate.getParameterTypes(); if (constructorToUse != null && argsToUse.length > paramTypes.length) { 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); } catch (UnsatisfiedDependencyException ex) { if (this.beanFactory.logger.isTraceEnabled()) { this.beanFactory.logger.trace( "Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex); } if (causes == null) { causes = new LinkedList<>(); } causes.add(ex); continue; } } else { if (paramTypes.length != explicitArgs.length) { continue; } argsHolder = new ArgumentsHolder(explicitArgs); } int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes)); 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.storeCache(mbd, constructorToUse); } } try { final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy(); Object beanInstance; if (System.getSecurityManager() != null) { final Constructor> ctorToUse = constructorToUse; final Object[] argumentsToUse = argsToUse; beanInstance = AccessController.doPrivileged((PrivilegedAction 这里代码很多,实现的逻辑也很复杂,其主要的作用就是解析参数并确定调用的构造方法;大概流程就是:先确定构造方法参数,接着根据构造参数确定构造方法,然后构造参数转换成构造方法中需要的参数类型,最后再次检查下是否有不确定的构造方法存在(方法的参数为父子关系)。这些所实现的是为了准备实例化需要的信息,最后的实例化是调用strategy.instantiate()完成的。
-
无参构造方法实例化:看完有参构造方法实例化的源码,再来看无参构造方法实例化就很简单了,
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; //获取系统的安全管理接口,JDK标准的安全管理API if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged((PrivilegedAction
因为无需对构造参数进行解析及构造方法的匹配查找,所以直接调用strategy.instantiate()来实例化就可以了。
综上我们能够看到,不管哪种实例化方式最后都是调用SimpleInstantiationStrategy#instantiate()(除了Supplier)完成Bean的创建,最后再封装成BeanWrapper对象返回。
我们先看下SimpleInstantiationStrategy的源码结构,
发现instantiate()方法是个重载方法,每个方法内的处理基本大同小异,我们这里选择无参构造函数调用的instantiate()来分析源码(它的其它重载方法有兴趣可以自己去看源码),
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
//判断Bean中有没有方法被覆盖
if (!bd.hasMethodOverrides()) {
Constructor> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
//检查Bean是否是一个接口
final Class> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction>) () -> clazz.getDeclaredConstructor());
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//使用反射实例化
return BeanUtils.instantiateClass(constructorToUse);
}
else {
//使用CGLIB实例化
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
一步步抽丝剥茧,到这里Bean实例化的最后结局已经完全展示在我们面前了,真相永远只有一个,那就是如果Bean中有方法被覆盖就通过JDK的反射机制创建对象,反之则使用CGLIB(一个字节码生成器的类库,AOP中会去详解)来创建。
4.2.提前缓存Bean
创建Bean并封装成BeanWrapper之后,往下调用了addSingletonFactory()方法,
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
protected void addSingletonFactory(String beanName, ObjectFactory> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
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;
}
不难发现Bean初始化完成前,需要对创建的Bean的beanName进行各种缓存,这样避免对象创建过程中的循环依赖,同时这里参数传入了一个创建的ObjectFatory对象,而它的使用地方,之前从缓存中获取Bean里也介绍过了,而缓存的时间就是在这里。
4.3.属性注入
既然Bean对象已经有了,那么接下来就是就要给它赋值,这里调用了populateBean()为Bean对象的属性进行注入,
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 {
return;
}
}
//实例化后处理
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//处理自动装配
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//根据名称自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//根据类型自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//属性值处理
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
//依赖检查
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
//属性注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
通过上面源码,我们知道这里做了这样的处理:
- 通过postProcessAfterInstantiation()对实例化的对象做一些处理,同时可以直接结束属性注入;
- 通过Bean的名称和类型注入属性值;
- 通过postProcessPropertyValues()对属性值进行处理;
- 执行依赖性检查以确保已设置所有公开的属性;
- 把获取的属性值注入到对象中。
我们先看下autowireByName()、autowireByType()方法的源码,
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//获取需要注入的属性名(对Bean对象中非简单属性(不是简单继承的对象,如8中原始类型,字符串,URL等都是简单属性)进行处理)
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
//判断IOC容器中是否包含beanName的Bean
if (containsBean(propertyName)) {
//获取Bean
Object bean = getBean(propertyName);
//属性赋值
pvs.add(propertyName, bean);
//注册缓存依赖的beanName
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//获取自定义类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//存放要注入的属性名
Set autowiredBeanNames = new LinkedHashSet<>(4);
//获取需要注入的属性名
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
//不对Object类型的属性进行注入
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//获取Bean
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
//属性赋值
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
//注册缓存依赖的beanName
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
通过上面对比的分析,总结它们的主要处理流程其实相差不多,都是:
- 调用unsatisfiedNonSimpleProperties()方法获取需要注入的属性名,主要筛除对Bean对象中的简单属性,比如基本数据类型(Integer、Boolean、Long等),字符串,URL等,通过类型注入的方式中对Object类型的属性不进行注入;
- 遍历属性名,获取依赖的Bean对象,其中通过类型注入的方式中是调用resolveDependency()获取的,包括实现了对@Value注解、List
、Array 、Map 、内部类、引用类型等类型的解析匹配等处理,但其本质也是调用BeanFactory#getBean()方法; - 注册缓存Bean和依赖的Bean的各自beanName关系。
通过上面的解析拿到属性名和对应的值之后,接下来就是调用applyPropertyValues()把PropertyValues给注入到对象中了,
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
//封装属性值
MutablePropertyValues mpvs = null;
List original;
if (System.getSecurityManager() != null) {
if (bw instanceof BeanWrapperImpl) {
//设置安全上下文,JDK安全机制
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
}
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
try {
//属性赋值
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
//获取原始类型值
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}
//自定义的类型转换
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//创建属性值解析器,将属性值解析为实际值
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
List deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
//无需转换
if (pv.isConverted()) {
deepCopy.add(pv);
}
//需要转换
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
if (resolvedValue == originalValue) {
if (convertible) {
//设置属性转换后的值
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
//设置属性转换后的值
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
try {
//属性赋值
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
而上面方法的中的bw.setPropertyValues()就是整个属性注入的点睛之笔了,具体调用的是AbstractNestablePropertyAccessor#setPropertyValue()方法,在里面实现更具体的解析处理赋值过程,感兴趣可以深入了解一下。
4.4.初始化Bean
上面已经完成了属性的注入,那么接下来我们还需要对Bean对象进行一个初始化操作,我们知道在配置元数据的时候,会有一个init-method的属性,它的作用是在Bean实例初始化前调用配置的方法,而这里就是这个配置方法调用的入口。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//JDK的安全机制验证权限
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
4.5.注册Bean
经历过复杂的Bean创建及属性注入实现之后,剩下通过registerDisposableBeanIfNecessary()方法注册Bean就很简单了,主要就是把Bean注册到Map
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
到这里,我们就已经完成了Bean的整个实例化到注册的过程了。
5.获取真正需要的Bean
但到这里还没结束,我们注意到每次实例化Bean之后,都会调用getObjectForBeanInstance()方法,那它作用是什么呢?我们先看下源码,
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
//Bean的名称以&开头,且不是FactoryBean则抛出异常
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
//尝试从缓存中获取Bean对象
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean> factory = (FactoryBean>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
//RootBeanDefinition转换,合并父类的属性
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
//通过FactoryBean获取获取Bean对象
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
protected Object getObjectFromFactoryBean(FactoryBean> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
//从缓存中获取Bean对象
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//创建Bean
object = doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
try {
//后置处理
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
}
//缓存Bean对象
this.factoryBeanObjectCache.put(beanName, object);
}
}
return object;
}
}
else {
//创建Bean
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
//后置处理
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
我们知道了它主要是用于检查当前的Bean是否是FactoryBean,不是直接返回,是则通过FactoryBean去创建Bean,而FactoryBean我们在准备工作中也介绍过了,上面代码中我们能看到具体的创建过程是交给doGetObjectFromFactoryBean()方法完成的,那我们看它里面到底是咋实现的,
private Object doGetObjectFromFactoryBean(final FactoryBean> factory, final String beanName) throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction
原来最后Bean的创建就是通过FactoryBean#getObject()方法完成的,而前面的解析我们也知道,其本质还是调用BeanFactory#getBean()。我们再看前面的代码,在拿到Bean实例之后并没有直接返回,而是调用postProcessObjectFromFactoryBean()方法,对从FactoryBean获得的对象进行后处理,它实际调用的是下面的代码,
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
//后置处理
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
主要是在Bean初始化之后做一些自定义的处理操作。纵观全文,发现源码中有很多对Bean的前置后置处理器,包括实例化前后处理、初始化前后处理等等,而Spring设计这样的规则的目的就是为了在实际开发中可以利用这些处理器回调自己扩展的业务逻辑,后面有机会的话会再单独拎出来讲讲。
6.类型转换
前面已经完成Bean的依赖注入了,到这里基本就是收尾了,主要解决的是当开始时通过getBean(String name, @Nullable Class
总结
最后也梳理了整个注入流程流程的时序图,而通过解析源码,我们再次验证了Bean的实例化入口离不开BeanFactory#getBean()方法,底层通过反射或者CGLIB代理完成对象创建,属性根据名称和类型自动注入等等,而本篇文章的目录结构就是提炼精简下来的流程。
参考资料:
- Spring官网文档
- Tom老师的Spring笔记
- Spring源码深度解析书籍
把一件事做到极致就是天分!