AbstractBeanFactory#getBean()、doGetBean完成Bean的初始化、实例化,以及BeanPostProcessor后置处理器分析
这篇文章主要讲解Spring IOC容器的主要内容:Bean的实例化、初始化。
通过之前跟踪Spring IOC刷新的源码,我们所有的剩余的单例Bean都是通过这一步:finishBeanFactoryInitialization(beanFactory);来进行初始化的。最重要的一个方法就为:DefaultListableBeanFactory#preInstantiateSingletons。
其内部核心方法为:getBean --> doGetBean方法
getBean方法概述
getBean()是顶层接口BeanFactory提供的,一共有五个原型:
Object getBean(String name) throws BeansException;
<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
// Spring2.5以后才有的接口
Object getBean(String name, Object... args) throws BeansException;
// Spring3.0以后才有的接口
<T> T getBean(Class<T> requiredType) throws BeansException;
// Spring4.1以后才有的接口
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
很多人都不理解这个args 是干什么用的,这里解释一下。首先我们要明白,getBean()内部不仅仅是get,如果get不到还可能去实例化一个Bean的(默认根据空构造函数进行实例化),因此本处的args其实就是为了匹配构造函数而提供的扩展功能~
使用前提:
- 传入的参数必须有相对应的构造函数入参与之匹配
- bean的scope必须设置成prototype,因为动态传参,bean不可以是单例的
AbstractBeanFactory作为抽象实现,复写了其中3个方法:
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
// 备注:此处的doGetBean,就是Bean实例化的核心逻辑
DefaultListableBeanFactory继承自AbstractBeanFactory,复写了剩余的2个方法:
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
return getBean(requiredType, (Object[]) null);
}
// 上面那个方法是调用这个方法的逻辑。
@Override
public <T> T getBean(Class<T> requiredType, @Nullable Object... args) throws BeansException {]
// resolveNamedBean里面的逻辑,也是根据requiredType去找的。若不止一个会抛错:NoUniqueBeanDefinitionException
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
// 从这里我们可以看到,如果子容器里没有找到Bean,还回去父容器(若存在的话)里找找看
BeanFactory parent = getParentBeanFactory();
if (parent != null) {
return (args != null ? parent.getBean(requiredType, args) : parent.getBean(requiredType));
}
throw new NoSuchBeanDefinitionException(requiredType);
}
那么接下来,我们就得看看这里面最核心的逻辑:doGetBean()
AbstractBeanFactory#doGetBean
依赖注入主要有两个过程,一个是实例化Bean,另一个是将依赖关系注入到Bean中
从命名上我们也可以看出:它是doGetBean,是有do这个动作的。因此不是简单的get有就返回,没有就返回null这么简单的操作。而是里面做了实例化、依赖注入、属性赋值、解决循环依赖等一些列操作。
先贴上源码:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 该方法作用:1、 如果是FactoryBean,会去掉Bean开头的&符号
// 2、能存在传入别名且别名存在多重映射的情况,这里会返回最终的名字,如存在多层别名映射A->B->C->D,传入D,最终会返回A
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// getSingleton()方法的实现,在父类DefaultSingletonBeanRegistry中,请先移步下面,看详解
//这里先尝试从缓存中获取,若获取不到,就走下面的创建
// 特别注意的是:这里面走创建(发现是个new的),就加入进缓存里面了 if (newSingleton) {addSingleton(beanName, singletonObject);} 缓存的字段为全局的Map:singletonObjects
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
// 这里虽然只是一句日志,但是能说明用意。
// 若条件为true,表示这个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 + "'");
}
}
// 在getBean方法中,getObjectForBeanInstance是个频繁使用的方法。因此为了更好的知道细节,下面会详解这个方法的
// 其实简单理解就是处理FactoryBean的getObject()方法
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 原型对象不允许循环创建,如果是原型对象正在创建,那就抛异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 这一步也是必须要做的,若存在父容器,得看看父容器是否实例化过它了。避免被重复实例化(若父容器被实例化,就以父容器的为准)
// 这就是为何,我们扫描controller,哪怕不加排除什么的,也不会出问题的原因~,因为Spring中的单例Bean只会被实例化一次(即使父子容器都扫描了)
BeanFactory parentBeanFactory = getParentBeanFactory();
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 {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//alreadyCreated字段增加此值。表示此Bean已经创建了
// 备注,此处我们就以 `helloServiceImpl` 这个Bean的创建为例了~~~
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 根据名字获取合并过的对应的RootBeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检查mbd是否为抽象的或mbd为单例,但存在args的情况(args只有初始化原型对象才允许存在)
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 这里就重要了,因为我们会有属性注入等等 所以这里就是要保证它依赖的那些属性先初始化才行
// 这部分是处理循环依赖的核心,这里稍微放一放。下面有大篇幅专门讲解这方面的以及原理解决方案
// @DependsOn注解可以控制Bean的初始化顺序~~~
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
// 从这里开始,就正式开始着手创建这个Bean的实例了~~~~
if (mbd.isSingleton()) {
// 也是一样先尝试从缓存去获取,获取失败就通过ObjectFactory的createBean方法创建
// 这个getSingleton方法和上面是重载方法,它支持通过ObjectFactory去根据Scope来创建对象,具体源码解析见下面
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.
// 执行失败,就销毁Bean。然后执行对应的destroy方法,等等销毁Bean时候的生命周期方法们~~~~~~~~~这个就不多说了 主要看看上面的createBean方法吧
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} 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.
// 这里就比较简单了,就是requiredType,比如要求是Integer,获得的是String,俺么就会调用转换器转换过来
// 绝大多数情况下,没啥卵用
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;
}
DefaultSingletonBeanRegistry#getSingleton
@Override
@Nullable
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 此处是先从已经缓存好了的singletonObjects的Map中,查看有木有(至于当前已经有哪些了,下面有个截图,相信什么时候进来的都应该有些印象吧)
Object singletonObject = this.singletonObjects.get(beanName);
// 若缓存里没有。并且,并且,并且这个Bean必须在创建中,才会进来。
// singletonsCurrentlyInCreation字段含义:会缓存下来所有的正在创建中的Bean,如果有Bean是循环引用的 会把这种Bean先放进去,这里才会有值
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;
}
DefaultSingletonBeanRegistry#getSingleton详解(根据ObjectFactory结合Scope来创建合适的对象):
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) {
// 如果这个Bean正在被销毁,就抛异常了
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!)");
}
// 创建前置检查:1、若在inCreationCheckExclusions面校验名单里,是ok的
//2、singletonsCurrentlyInCreation把它添加进去,证明这个Bean正在创建中
beforeSingletonCreation(beanName);
// 此处先打标机为为false
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 把这个实例生成出来,并且标志位设为true
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.
// in the meantime再次旗舰,若有人已经把这个Bean放进去了,那就抛出这个异常吧
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
} catch (BeanCreationException ex) {
// 处理异常
// 比如我们经常遇到的UnsatisfiedDependencyException异常:@Autowired的时候找不到依赖的Bean就是这个异常(一般由NoSuchBeanDefinitionException这个异常导致)
// 这里会吧异常链接拼接起来,然后一起打印出来~~~~非常方便查找问题
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 创建完成后再检查一遍。做的操作为:从正在创建缓存中移除
afterSingletonCreation(beanName);
}
// 这里也非常重要:若是新的Bean,那就执行addSingleton这个方法,这个方法做了什么,就下面4步操作:
//this.singletonObjects.put(beanName, singletonObject); //缓存起来
//this.singletonFactories.remove(beanName); //把对应ObjectFactory的缓存移除
//this.earlySingletonObjects.remove(beanName);
//this.registeredSingletons.add(beanName);
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
AbstractBeanFactory#createBean 开始创建Bean
AbstractAutowireCapableBeanFactory是AbstractBeanFactory的子类,实现了createBean的具体逻辑。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 确保对应BeanClass完成解析(已经加载进来了Class对象)具体表现是进行了ClassLoder.loadClass或Class.forName完成了类加载
// 主要根据传入的typesToMatch生成特定的ClassLoader,之后还要调用RootBeanDefinition#resolveBeanClass,根据特定的加载器或者默认加载器加载出class属性对应的Class对象
// 我们这里解析出来,显然就是class com.fsx.service.HelloServiceImpl这个Class了
// 判断需要创建的Bean是否可以实例化,这个类是否可以通过类装载器来载入(也就说它甚至可能来源于网络)
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 这里主要是解析<lookup-method name="getFruit" bean="bananer"/>类似这种方式的依赖注入(Spring支持lookup-method,replace-method两个依赖注入的方式)
// 它相当于调用指定类里面的指定方法进行注入,所以需要考虑到方法重载的情况,因此这个方法解析的就是这种情况
// 由于项目中一般这么使用,也非常的不大众,具体原理此处省略
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 从doc解释:给BeanPostProcessors一个机会来返回一个代理对象代替目标对象 什么动态代理之类的,都在这里实现的~~~~~~~~~~~~~~~~~~~
// 1、具体逻辑是判断当前Spring容器是否注册了实现了InstantiationAwareBeanPostProcessor接口的后置处理器如果有,则依次调用其中的applyBeanPostProcessorsBeforeInstantiation方法,如果中间任意一个方法返回不为null,直接结束调用。
// 2、然后依次所有注册的BeanPostProcessor的postProcessAfterInitialization方法(同样如果任意一次返回不为null,即终止调用。
// 这个方法也非常的重要,后续有详细讲解
// 容器里所有的InstantiationAwareBeanPostProcessors实例,都会在此处生效,进行前置处理~~~~~~~~~~
// 下面有解释:BeanPostProcessor和InstantiationAwareBeanPostProcessor的区别,可以分清楚他们执行的时机
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);
}
// 这里又是一个核心逻辑:doCreateBean 创建Bean
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
// 创建完成后 直接短路掉返回
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);
}
}
resolveBeforeInstantiation详解:
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// beforeInstantiationResolved 这个属性如果是false,表示不需要被前置处理了
// 然后,唯一能改变它的值的地方,是下面这仅仅一行代码而已,它的访问权限为package
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// 这里hasInstantiationAwareBeanPostProcessors()方法就是看属性hasInstantiationAwareBeanPostProcessors的值。就是标记容器里是否有InstantiationAwareBeanPostProcessor的实现
// 显然,在执行addBeanPostProcessor,发现这个Bean是这个子类型的时候,就会设为true了。同理的还有hasDestructionAwareBeanPostProcessors这个属性,表示销毁的处理器
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 拿到最终的目标类型(放置被别的包装过)显然此处是;com.fsx.service.HelloServiceImpl
// 可能依赖于AbstractBeanFactory#resolveBeanClass这个方法去解析
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 先执行执行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation回调方法
// 里面的逻辑也比较简单:拿到缓存好的(List装着的)所有的BeanPostProcessors,如果是InstantiationAwareBeanPostProcessor就执行吧~~
// 只要有一个result不为null;后面的所有 后置处理器的方法就不执行了,直接返回(所以执行顺序很重要)
//1、ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor这个内部类就是这个类型。主要还是去增强、完善处理@Configuration这种类 但是它并没有重写postProcessBeforeInstantiation这个方法,所以默认是返回null的
//2、CommonAnnotationBeanPostProcessor/Autowired。。。也没做处理(若你自己不去注册,那系统里就再没有了)
// 需要注意的是,如果我们采用了AOP、声明式事务等等,这里就会有了,后面又会回来讲解这一块
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
// 我们可以看到,如果bean不为null,那就直接返回了 短路掉后面的After也就不执行了
if (bean != null) {
// 注意,这里是Initialization,是初始化的后置方法,是BeanPostProcessor的方法,也就是说初始化完成后的方法。
// 为何这里执行这个方法呢?是因为我们上面说了,如果返回不为null,后面都都会被短路掉。但是此处Spring还是让我们执行了初始化后的处理器方法,这点需要引起注意
// 就是说:即使Bean在实例化前已经返回了一个不为null的对象,别的方法都被短路了,但是我的【初始化】后处理器方法applyBeanPostProcessorsAfterInitializationh还是可以执行的
// 这里面可以关注一下这个类:ApplicationListenerDetector
//初始化之后的方法返回了null,那就需要调用doCreateBean生成对象了==============
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
BeanPostProcessor、InstantiationAwareBeanPostProcessor、SmartInstantiationAwareBeanPostProcessor和MergedBeanDefinitionPostProcessor
这几个接口,是比较容易搞混的,这里需要区分一下。
InstantiationAwareBeanPostProcessor代表了Spring的另外一段生命周期:实例化。先区别一下Spring Bean的实例化和初始化两个阶段的主要作用:
- 实例化:实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中
- 初始化:初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性
所以现在就清楚了:InstantiationAwareBeanPostProcessor是作用于 实例化 前后,所以是先执行的。BeanPostProcessor是作用于 初始化 前后,给Bean各个属性赋值的时候执行的(比如我们的属性依赖注入,都是这个时候生效的)
BeanPostProcessor中的方法是初始化类时候的处理器(实例化早于初始化)在spring中初始化指的一般是在调用init-method属性前后
// 咋一看,以为方法名都一样?哈哈 其实你区分出来两个单词的意思,就明白了
// Instantiation:[ɪnstænʃɪ'eɪʃən] 实例化,例示
// Initialization:[ɪˌnɪʃəlaɪ'zeɪʃn] 初始化,设定初始值
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
//子接口:InstantiationAwareBeanPostProcessor
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
内部类:BeanPostProcessorChecker实现了postProcessAfterInitialization方法:输出了一行日志而已
ApplicationListenerDetector重点实现了postProcessAfterInitialization方法:那些实现了接口ApplicationListener的bean,在它们创建时初始化之后,将它们添加到应用上下文的事件多播器上。并在这些ApplicationListener bean销毁之前,将它们从应用上下文的事件多播器上移除。
子接口SmartInstantiationAwareBeanPostProcessor 继承自 InstantiationAwareBeanPostProcessor;但是SmartInstantiationAwareBeanPostProcessor多了一个三个方法
// 从名字上,它有个Smart,是比较智能一些的
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
// 预测Bean的类型,返回第一个预测成功的Class类型,如果不能预测返回null
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
// 选择合适的构造器,比如目标对象有多个构造器,在这里可以进行一些定制化,选择合适的构造器
// beanClass参数表示目标实例的类型,beanName是目标实例在Spring容器中的name
// 返回值是个构造器数组,如果返回null,会执行下一个PostProcessor的determineCandidateConstructors方法;否则选取该PostProcessor选择的构造器
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
// 获得提前暴露的bean引用。主要用于解决循环引用的问题
// 只有单例对象才会调用此方法
// 在我们准们处理讲解循环引用的时候,这个方法会起到比较关键的作用
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
这个接口有什么作用的呢?这里举例两个实现,有个感觉就行:
比如AutowiredAnnotationBeanPostProcessor:依赖注入时的泛型依赖注入,就通过这个智能判断类型来注入。
泛型依赖注入的优点:允许我们在使用spring进行依赖注入的同时,利用泛型的优点对代码进行精简,将可重复使用的代码全部放到一个类之中,方便以后的维护和修改。比如常用的Base设计。(属于Spring 4.0的新特性)
Spring4.0之后,这样是不报错的:
@Configuration
public class MyConfiguration {
@Bean
public BaseRepository<Student> studentRepository() {
return new BaseRepository<Student>() {};
}
@Bean
public BaseRepository<Faculty> facultyRepository() {
return new BaseRepository<Faculty>() {};
}
}
// 注意,这里能够正确注入到正确的Bean,虽然他们都是BaseRepository类型。但是在Spring4.0之后,泛型里面的东西
// 也可以作为一种分类Qualifier,随意这里虽然都是BaseRepositor类型,但是在容器中还是被分开了的
@Autowired private BaseRepository<Student> studentRepo;
@Autowired private BaseRepository<Faculty> facultyRepo;
另外Spring-AOP包下有很多实现,比如我们最熟悉的:AnnotationAwareAspectJAutoProxyCreator等等这种类。
子类MergedBeanDefinitionPostProcessor:
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
//来给后续回调中缓存一些meta信息使用
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
}
用来将merged BeanDefinition暴露出来的回调。看看它的一些主要实现:
//InitDestroyAnnotationBeanPostProcessor
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
metadata.checkConfigMembers(beanDefinition);
}
//CommonAnnotationBeanPostProcessor
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
//AutowiredAnnotationBeanPostProcessor
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
//ApplicationListenerDetector
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
this.singletonNames.put(beanName, beanDefinition.isSingleton());
}
总结一下:InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置
- postProcessBeforeInstantiation方法是最先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走
- postProcessAfterInstantiation方法在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。因为它的返回值是决定要不要调用postProcessPropertyValues方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true,postProcessPropertyValues就会被执行
- postProcessPropertyValues方法对属性值进行修改(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值)。如果postProcessAfterInstantiation方法返回false,该方法可能不会被调用。可以在该方法内对属性值进行修改
父接口BeanPostProcessor的2个方法postProcessBeforeInitialization和postProcessAfterInitialization都是在目标对象被实例化之后,并且属性也被设置之后调用的
Instantiation表示实例化,Initialization表示初始化。实例化的意思在对象还未生成,初始化的意思在对象已经生成。
创建Bean的最终方法,绝大多数Bean的实例化、初始化都会走这里:AbstractAutowireCapableBeanFactory#doCreateBean
spring的ioc创建bean的最核心代码
讲解之前,先了解下BeanWrapper:
BeanWrapper 是Spring提供的一个用来操作javaBean属性的工具,使用它可以直接修改一个对象的属性。
BeanWrapper大部分情况下是在spring ioc内部进行使用,通过BeanWrapper,spring ioc容器可以用统一的方式来访问bean的属性。用户很少需要直接使用BeanWrapper进行编程。
对于bean属性的操作,我们熟知的主要有下面这些工具类:
- Apache的BeanUtils和PropertyUtils
- cglib的BeanMap和BeanCopier
- spring的BeanUtils
Spring中BeanWrapper 的主要在于如下三点:
- 支持设置嵌套属性
- 支持属性值的类型转换(设置ConversionService)
- 提供分析和操作标准JavaBean的操作:获取和设置属性值(单独或批量),获取属性描述符以及查询属性的可读性/可写性的能力
public interface BeanWrapper extends ConfigurablePropertyAccessor {
//为数组和集合自动增长指定一个限制。在普通的BeanWrapper上默认是无限的。
void setAutoGrowCollectionLimit(int autoGrowCollectionLimit);
//返回数组和集合自动增长的限制。
int getAutoGrowCollectionLimit();
//如果有的话,返回由此对象包装的bean实例
Object getWrappedInstance();
//返回被包装的JavaBean对象的类型。
Class<?> getWrappedClass();
//获取包装对象的PropertyDescriptors(由标准JavaBeans自省确定)。
PropertyDescriptor[] getPropertyDescriptors();
//获取包装对象的特定属性的属性描述符。
PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException;
}
BeanWrapperImpl是Spring提供的唯一实现类。
doCreateBean源码解析
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 用BeanWrapper来持有创建出来的Bean对象
BeanWrapper instanceWrapper = null;
//如果是单例的话,则先把缓存中的同名bean清除(同名的)
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
//实际创建的交给createBeanInstance来完成,
//bean的生成,这里会使用默认的类生成器,包装成BeanWrapperImpl类,为了下面的populateBean方法的属性注入做准备
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
//如果不是NullBean,则将resolvedTargetType 属性设置为当前的WrappedClass
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 此处处理这个接口的处理器:MergedBeanDefinitionPostProcessor,他在BeanPostProcessor的基础上增加了postProcessMergedBeanDefinition方法,在此处就被调用了
// 主要是处理@PostConstruct,@Autowire,@Value,@Resource,@PreDestory等这些注解。(显然对应哪去处理器,一目了然了) 下面会举例看看AutowiredAnnotationBeanPostProcessor的处理
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//如果当前bean是单例,且支持循环依赖,且当前bean正在创建,通过往singletonFactories添加一个objectFactory,这样后期如果有其他bean依赖该bean 可以从singletonFactories获取到bean
//getEarlyBeanReference可以对返回的bean进行修改,这边目前除了可能会返回动态代理对象 其他的都是直接返回bean
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");
}
// 这里面主要是解决循环引用问题~~~~~~~~~借助了这个工厂
//这里主要是调用处理器:SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference方法去寻找到前期的Bean们(若存在这种处理器的话)
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
// 这个Obj,就是最终要返回的对象了
Object exposedObject = bean;
try {
// 这又是非常非常重要的一步:给已经初始化的属性们赋值===================对bean进行填充,在这里面完成依赖注入的相关内容
// 啥都不说了,看下面的详解吧
populateBean(beanName, mbd, instanceWrapper);
//完成属性依赖注入后,进一步初始化Bean 具体进行了以下操作:
//若实现了BeanNameAware, BeanClassLoaderAware,BeanFactoryAwareAware等接口,则注入相关对象
//遍历后置处理器,调用实现的postProcessBeforeInitialization方法,
//如果实现了initialzingBean,调用实现的 afterPropertiesSet()
//如果配置了init-mothod,调用相应的init方法
//遍历后置处理器,调用实现的postProcessAfterInitialization
// 关于populateBean和initializeBean的详解,下贴出了博文链接参考~~~~~~
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);
}
}
//如果earlySingletonExposure为true,尝试从缓存获取该bean(一般存放在singletonFactories对象通过调用getObject 把对象存入earlySingletonObjects),
// 分别从singletonObjects和earlySingletonObjects获取对象 这里依然是处理循环依赖相关问题的
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 {
// 如果有需要,就注册DisposableBean,这样Bean销毁的时候此种后置处理器也会生效了
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
doCreateBean主要依赖createBeanInstance 和 populateBean两个方法。
在 createBeanInstance 中生成了Bean所包含的java对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//一样的,确保bean类实际上已经解析过了,可以实例化
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//确保class不为空,并且访问权限为public 所以注意如果你的Class不是public的,Spring给你创建不了对象
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());
}
// 配置的一种特殊的callback回调方法,通过这个callback创建bean
// Supplier返回的Obj,最终会交给obtainFromSupplier包装成BeanWrapper
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 这是Spring支持的又一种方式:使用工厂方法来进行bean的实例化
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
// 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析
// 此部分在循环依赖中,会有更深入的说明~~~~~~~~~~~~~~~~
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 标记一下,已经解析过class的构造器
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// resolved若为true,表示已经解析过构造器了,就下面直接使用解析好的构造器实例化Bean
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
// Need to determine the constructor...
// 通过此方法,去检测到一个可用的构造器:这里面智能使用SmartInstantiationAwareBeanPostProcessor啦,它通过循环调用处理器的determineCandidateConstructors方法,谁第一个发现一个可用的构造器,就return,否则返回null
// 详情见下面讲解AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors方法的讲解
// 这里需要注意:如果你的Bean没有空的构造函数(比如只有一个参数的构造函数,那么Spring会用这个构造函数给你实例化Bean,并且入参会自动帮你从容器里去找出来)
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors:检测出候选的构造器们(也就是我们常说的:构造器注入)
检测Bean的构造器,可以检测出多个候选构造器,再有相应的策略决定使用哪一个。它将自动扫描通过@Autowired/@Value注解的构造器从而可以完成构造器注入
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// Let's check for lookup methods here..
// 检测@Lookup注解,这个注解的注入方式,已经不推荐使用了===========
if (!this.lookupMethodsChecked.contains(beanName)) {
try {
ReflectionUtils.doWithMethods(beanClass, method -> {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition) beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
this.lookupMethodsChecked.add(beanName);
}
// Quick check on the concurrent map first, with minimal locking.
// 先从缓存里去看,有没有解析过此类的构造函数~~~
//对每个类的构造函数只解析一次,解析完会存储结果,以备下次复用
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
// Fully synchronized resolution now...
synchronized (this.candidateConstructorsCache) {
// 为了线程安全,这里继续校验一次
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor<?>[] rawCandidates;
try {
// 拿到此Class所有的构造函数们(一般的类都只有一个空的构造函数) 当然我们也可以写多个
rawCandidates = beanClass.getDeclaredConstructors();
} catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
// 兼容Kotlin类型做的处理~~~~~~~~~~~~
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
// 遍历处理每个每个构造器~~~~~~~~~~~~~~~~~~
for (Constructor<?> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
// 找到构造器里有@Aotowaired或者@Value注解的直接信息们
AnnotationAttributes ann = findAutowiredAnnotation(candidate);
if (ann == null) {
// 此方法的目的是拿到目标类:比如若是被cglib代理过的,那就拿到父类(因为cglib是通过子类的形式加强的)
Class<?> userClass = ClassUtils.getUserClass(beanClass);
// 说明确实是被CGLIB代理过的,那就再解析一次 看看父类是否有@Autowaired这种构造器
if (userClass != beanClass) {
try {
Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
} catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
// 这里是是存在注解标注的这种构造器的
if (ann != null) {
// 这个判断很有必要,表示要求的构造器最多只能有一个
//画外音:@Autowired标注的构造器数量最多只能有一个(当然,required=true的只能有一个,=false的可以有多个)
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
//获取autowire注解中required属性值
boolean required = determineRequiredStatus(ann);
// 只有是true,就往下走(默认值为true)
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
// 这样子,这个构造器就是必须的了,记录下来
requiredConstructor = candidate;
}
// 把标注有@Autowired注解的构造器,记录下来,作为候选的构造器
candidates.add(candidate);
}
// 这个就重要了,处理精妙
// 若该构造器没有被标注@Autowired注解,但是它是无参构造器,那就当然候选的构造器(当然是以标注了@Autowired的为准)
else if (candidate.getParameterCount() == 0) {
// 这里注意:虽然把默认的构造函数记录下来了,但是并没有加进candidates里
defaultConstructor = candidate;
}
}
// 若能找到候选的构造器,这里注意,如果仅仅只有一个构造器的情况(没有标注@Autowired注解),这个亏胡原始股fakse,下面的elseif会处理的。。。。
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
// 这个是candidates里面有值了,并且还没有requiredConstructor (相当于标注了注解@Autowired,但是required=false) 的情况下,会吧默认的构造函数加进candidates
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
//如果没有默认的无参构造函数,且有@Autowired(required = false)的构造函数,则发出警告信
else if (candidates.size() == 1 && logger.isWarnEnabled()) {
logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
// 这个意思是:有且仅有一个构造器,并且该构造器的参数大于0个,那就是我们要找的构造器了
// 这种情况,也是平时我们使用得比较多的情况
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
// 处理primaryConstructor以及nonSyntheticConstructors 兼容Kotlin一般都达不到
else if (nonSyntheticConstructors == 2 && primaryConstructor != null
&& defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
// 啥构造器都没找到,那就是空数组
else {
candidateConstructors = new Constructor<?>[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
// 若有多个构造函数,但是没有一个标记了@Autowired,此处不会报错,但是返回null,交给后面的策略处理
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
可能有小伙伴会问:其实最终找到的构造器都是一个,这里为何返回一个数组呢?如果是这么认为,那你就还是没有太完全理解这里面的处理原理,比如下面情况:
@Service
public class HelloServiceImpl implements HelloService {
private ApplicationContext applicationContext;
private BeanFactory beanFactory;
@Autowired(required = false)
public HelloServiceImpl(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Autowired(required = false)
public HelloServiceImpl(ApplicationContext applicationContext, BeanFactory beanFactory) {
this.applicationContext = applicationContext;
this.beanFactory = beanFactory;
}
}
这里返回的是2个构造器。这里最终会执行2个参数的构造器。这种情况:
private ApplicationContext applicationContext;
private BeanFactory beanFactory;
HelloServiceImpl() {
System.out.println("我是空构造~");
}
@Autowired(required = false)
public HelloServiceImpl(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Autowired(required = false)
public HelloServiceImpl(ApplicationContext applicationContext, BeanFactory beanFactory) {
this.applicationContext = applicationContext;
this.beanFactory = beanFactory;
}
会返回3个构造器。最终执行的,还是参数最多的那个构造器。若返回多个构造器,Spring具体的执行策略,下面继续说:
Spring初始化Bean的执行策略(实例化Bean的过程)
主要处理代码如下:
if (ctors != null ||
// 或者标注了处理机制是构造器注入方式 AbstractBeanDefinition#setAutowireMode可以设置模式
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 构造器选择策略,注入逻辑
return autowireConstructor(beanName, mbd, ctors, args);
}
ConstructorResolver#autowireConstructor:这个方法作用是获取被包装后的bean,包装后的对象是BeanWrapper对象,这个对象的实现类是BeanWrapperImpl。其中包含被封装后待处理的bean,和设置bean属性的属性编辑器。
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
// 此处的this,就是DefaultListableBeanFactory嘛
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
// ConstructorResolver#autowireConstructor
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable final Object[] explicitArgs) {
//先实例化一个BeanWrapperImpl类对象
BeanWrapperImpl bw = new BeanWrapperImpl();
// initBeanWrapper做了一些事,比如注册解析器、value解析器等等 这是个比较大的概念,后面会有专题再说吧
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
//如果构造参数不为空就直接使用这些参数即可
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
// 否则构造函数的入参,交给Spring处理。它会去容器里拿~~~~~
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
//获取已缓存解析的构造函数或工厂方法(resolvedConstructorOrFactoryMethod----用于缓存已解析的构造函数或工厂方法)
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
//如果缓存不为空,并且构造参数已经解析缓存了,(constructorArgumentsResolved为包可见,用于表示构造参数状态是否已经解析)
// 显然首次进来,都是为null并且没有被解析的
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
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);
}
}
//如果缓存的构造器不存在,就说明没有bean进行过解析,需要去关联对应的bean的构造器
if (constructorToUse == null) {
// Need to resolve the constructor.
// 我们的传值chosenCtors 显然不为null,所以此值为true
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.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);
}
// Take specified constructors, if any.
//如果传入的构造器为空,则获取bean的Class对象,然后根据bean是不是public修饰的来按照不同的方式获取所有的构造器
// 显然,我们这里(大都都会有构造器)
// 但是此处我们发现,即使构造器不是public的,这里也能够遭到构造器来进行实例化
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
//getDeclaredConstructors返回所有的构造器(包括public和private修饰的),getConstructors返回public修饰的
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);
}
}
// 这个构造器排序有点意思
//按照访问方式和数量对构造器进行排序;public>protect>private,在同为public时构造器入参多的排在前面
// 所以排在第一位的,是public的,参数最多的构造器
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
// 记录下,引起歧义的构造器们。就是记录下来,如果存在这种歧义,抛异常的时候用来告诉调用者
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
// 开始遍历排序后的构造器了==========================
for (Constructor<?> candidate : candidates) {
// 拿到构造器参数的类型们
Class<?>[] paramTypes = candidate.getParameterTypes();
// constructorToUse不为null(表示已经找到了合适构造器),但是呢,连参数个数的长度都对应不上,那就直接break,后面的构造器全都不用看了
if (constructorToUse != 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 {
//兼容JDK6提供的@ConstructorProperties这个注解,如果它标注了参数名,那就以它的名字为准
//@ConstructorProperties的作用=======》构造函数上的注解,显示该构造函数的参数如何与构造对象的getter方法相对应
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
// 否则,就自己解析
if (paramNames == null) {
// 一般都是Bean工厂默认的DefaultParameterNameDiscoverer 解析出变量名
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);
}
// 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);
}
//lenientConstructorResolution的值ture与false有什么区别:
//这个属性默认值是true,在大部分情况下都是使用[宽松模式],即使多个构造函数的参数数量相同、类型存在父子类、接口实现类关系也能正常创建bean。
// false表示严格模式。与上面相反
// typeDiffWeight:返回不同的个数的权重(权重概念?)
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 根据权重,选择一个最为合适的构造器
if (typeDiffWeight < minTypeDiffWeight) {
// 大都进这里来,然后是木有ambiguousConstructors 的
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);
}
}
//下面步骤都是通用的,用上面得到的构造器(无论是从bean对象中获取的还是spring自己构建的)
// 和参数来反射创建bean实例,并放到BeanWrapperImpl对象中然后返回
try {
// 拿到生成Bean实例化策略,默认值为CglibSubclassingInstantiationStrategy 用CGLIB生成子类的方式
final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
beanFactory.getAccessControlContext());
}
else {
// 主要就是调用了策略器的instantiate,对Bean进行了最终的实例化
// 此方法为重载方法,此处因为不需要代理,所以执行的直接是SimpleInstantiationStrategy#instantiate
// 到此处,有一个HelloServiceImpl正式创建 然后继续到doCreateBean方法去吧
beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
bw.setBeanInstance(beanInstance);
return bw;
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
populateBean和initializeBean
一个是属性赋值的populateBean()(依赖注入),一个是赋值后对Bean的一些初始化操作:initializeBean()
AbstractAutowireCapableBeanFactory#populateBean实现依赖注入
在完成Bean实例化后,Spring容器会给这个Bean注入相关的依赖Bean,在源码中,这一步通过类AbstractAutowireCapableBeanFactory中的populateBean方法完成。
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;
//给InstantiationAwareBeanPostProcessors最后一次机会在属性注入前修改Bean的属性值
//具体通过调用postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//postProcessAfterInstantiation 这个方法返回true,后面的处理器才会继续执行,单反返回false,后面的就不会再执行了
//并且continueWithPropertyPopulation 打上标记表示false,也就是说后面的属性复制就不会再执行了
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 处理器若告知说不用继续赋值了,那就以处理器的结果为准即可
if (!continueWithPropertyPopulation) {
return;
}
//pvs是一个MutablePropertyValues实例,里面实现了PropertyValues接口,提供属性的读写操作实现,同时可以通过调用构造函数实现深拷贝
//本例中,我们的helloServiceImpl的Bean定义里,pvs为null
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//根据Bean配置的依赖注入方式完成注入,默认是0,即不走以下逻辑,所有的依赖注入都需要在xml(或者@Bean中)文件中有显式的配置
//如果设置了相关的依赖装配方式,会遍历Bean中的属性,根据类型或名称来完成相应注入,无需额外配置
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
// 深拷贝当前已有的配置
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
// 根据名称进行注入(见下)
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
// 根据类型进行注入(见下)
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
//结合注入后的配置,覆盖当前配置
pvs = newPvs;
}
// 显然hasInstAwareBpps=true,
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否进行依赖检查 默认值就是None 所以此处返回false,表示不需要依赖检查(关于依赖检查的4种模式,建议使用@Required来显示控制)
//@Required注解作用于Beansetter方法上,用于检查一个Bean的属性的值在配置期间是否被赋予或设置(populated)
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// 过滤出所有需要进行依赖检查的属性编辑器
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
// 在这个节点上:调用了InstantiationAwareBeanPostProcessor#postProcessPropertyValues方法,
// 若返回null,整个populateBean方法就结束了=============
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 关于postProcessPropertyValues的实现,有几个处理器是非常关键的:
// 比如AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor等等,且看下面的分解
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
// 若返回null,Spring表示你已经属性值都设置好了,那他也不再管了
if (pvs == null) {
return;
}
}
}
}
// 显然,现在大多数情况下,都不会在check这个了
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
// 将pvs上所有的属性填充到BeanWrapper对应的Bean实例中
// 注意:这一步完成结束后为止。我们的HelloServiceImpl这个Bean依赖的parent,还只是RuntimeBeanReference类型,还并不是真实的Parent这个Bean
//在Spring的解析段,其它容器中是没有依赖的Bean的实例的,因此这个被依赖的Bean需要表示成RuntimeBeanReferenc对象,并将它放到BeanDefinition的MutablePropertyValues中。
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
先看看autowireByName和autowireByType这两步是怎么实现的:
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//根据bw的PropertyDescriptors,遍历出所有可写的(即set方法存在),存在于BeanDefinition里的PropertyValues,且不是简单属性的属性名
//简单属性的判定参照下面方法,主要涵盖基本类型及其包装类,Number,Date等=============
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
// 显然,只有容器里存在的,才能根据这个名称注册进去。
//注意,这里存在,有点意思:含有Bean,或者Bean定义等等都算
/** @Override
public boolean containsBean(String name) {
String beanName = transformedBeanName(name);
// 首先工厂里必须有单例Bean,或者bean定义
// 然后还必须不是BeanFactory(不是&打头),或者是FactoryBean 就算是包含这个Bean的
if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
}
// Not found -> check parent. 看看父容器里有木有
BeanFactory parentBeanFactory = getParentBeanFactory();
return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
} */
// 再说明一下containsLocalBean这个方法,和containsBean的区别在于它只在自己的容器里找,不去父容器里找,其余的一样
if (containsBean(propertyName)) {
// 注意:此处找到依赖了,调用了getBean(),所以即使你现在仅仅只是Bean定义,那么会被创建实例对象
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 注册依赖关系
// 此处需要知道的是:Spring中使用dependentBeanMap和dependenciesForBeanMap来管理这些Bean的依赖关系:
//Map<String, Set<String>> dependentBeanMap:存放着当前Bean被引用的Bean的集合
//Map<String, Set<String>> dependenciesForBeanMap:存放的则是当前Bean所依赖的Bean的集合
//依赖注入的具体实现是在BeanWrapperImpl类中的setPropertyValue方法里=======================
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) {
// 类型转换器,如果没有指定,就用BeanWrapper这个转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
//如果是Object类型不进行装配==============
if (Object.class != pd.getPropertyType()) {
// 获取相关的写方法参数
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
// 看看实例是否实现了PriorityOrdered接口,若没有实现 就稍后点加载吧-----
boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
// 这里会根据传入desc里的入参类型,作为依赖装配的类型
// 再根据这个类型在BeanFacoty中查找所有类或其父类相同的BeanName
// 最后根据BeanName获取或初始化相应的类,然后将所有满足条件的BeanName填充到autowiredBeanNames中。
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
// 需要注入的依赖都拿到后,就开始注册这些依赖吧
for (String autowiredBeanName : autowiredBeanNames) {
// 一样的 这里注册这些依赖
registerDependentBean(autowiredBeanName, beanName);
}
autowiredBeanNames.clear();
}
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor#postProcessPropertyValues实现注解给属性赋值:从上面看到了,Bean已经解析拿到了注解的一些元信息,因此此处就调用一些处理器的postProcessPropertyValues方法,来给赋值了:
//AutowiredAnnotationBeanPostProcessor:这里就是解析该Bean的Autowired信息,然后给inject进去
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
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;
}
//CommonAnnotationBeanPostProcessor:逻辑和上面一毛一样,它处理的JSR-250的注解,比如@Resource
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
}
//RequiredAnnotationBeanPostProcessor:它就是去校验,标注了@Required注解的,必须是是存在这个Bean的
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
if (!this.validatedBeanNames.contains(beanName)) {
if (!shouldSkip(this.beanFactory, beanName)) {
List<String> invalidProperties = new ArrayList<>();
for (PropertyDescriptor pd : pds) {
if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) {
invalidProperties.add(pd.getName());
}
}
if (!invalidProperties.isEmpty()) {
throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
}
}
this.validatedBeanNames.add(beanName);
}
return pvs;
}
InjectionMetadata#inject处理依赖注入:
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
// 主要的方法,还是在InjectedElement#inject里
element.inject(target, beanName, pvs);
}
}
}
InjectedElement实现如下:
这里我们就以最常用的AutowiredFieldElement为例讲解(它是一个普通内部类,为private的):
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 拿到这个字段名
Field field = (Field) this.member;
Object value;
// 大多数情况下,这里都是false
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
} else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
// 转换器,没有手动注册,默认都是SimpleTypeConverter===============
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 把当前bean所依赖的这个Bean解析出来(从Spring容器里面拿,或者别的地方获取吧~~~)
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
// 如果已经拿到了这个Bean实例,
if (value != null || this.required) {
this.cachedFieldValue = desc;
// 把该Bean的依赖关系再注册一次
registerDependentBeans(beanName, autowiredBeanNames);
// 因为是按照类型注入,所以肯定只能指导一个这个的依赖Bean,否则上面解析就已经报错了
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
// 这里是来处理放置缓存的字段值
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
} else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
// 给该对象的该字段赋值。注意这里makeAccessible设置为true了,所以即使你的字段是private的也木有关系哦~~~
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
initializeBean进行Bean的初始化工作
上面步骤已经完成了Bean的属性的赋值工作,接下里就进行Bean的一些初始化工作,其中包括:
- Bean后置处理器初始化
- Bean的一些初始化方法,执行init-method等等
- Bean的实现的生命周期相关接口的属性注入
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 第一步:先执行所有的AwareMethods,具体如下代码,比较简单
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 执行所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器方法
// 规则:只要谁反悔了null,后面的就都不要执行了
// 这里面实现postProcessBeforeInitialization 的处理器就很多了,有很多对Aware进行了扩展的,具体如下面的具体介绍吧=================
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//这里就开始执行afterPropertiesSet(实现了InitializingBean接口)方法和initMethod
// 备注:这里initMethod方法的名称不能是afterPropertiesSet,并且这个类不是 InitializingBean类型才会调用,需要特别注意。
//(然后该方法只有方法名,所以肯定是反射调用,效率稍微低那么一丢丢)
// 由此可以见,实现这个接口的初始化方法,是在标注形如@PostConstruct之后执行的
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 整个Bean都初始化完成了,就执行后置处理器的这个方法
// 如果谁反悔了null,后面的处理器都不会再执行了
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
invokeAwareMethods:相关Aware接口为:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware这些都是spring将数据暴露出去的一种方式,我们直接实现这个接口就能拿到了~
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
applyBeanPostProcessorsBeforeInitialization的重要实现解释如下:
//ApplicationContextAwareProcessor:核心处理为
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
//BeanValidationPostProcessor:对bean进行数据校验
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!this.afterInitialization) {
doValidate(bean);
}
return bean;
}
//BootstrapContextAwareProcessor
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (this.bootstrapContext != null && bean instanceof BootstrapContextAware) {
((BootstrapContextAware) bean).setBootstrapContext(this.bootstrapContext);
}
return bean;
}
//ServletContextAwareProcessor:
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (getServletContext() != null && bean instanceof ServletContextAware) {
((ServletContextAware) bean).setServletContext(getServletContext());
}
if (getServletConfig() != null && bean instanceof ServletConfigAware) {
((ServletConfigAware) bean).setServletConfig(getServletConfig());
}
return bean;
}
//LoadTimeWeaverAwareProcessor
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof LoadTimeWeaverAware) {
LoadTimeWeaver ltw = this.loadTimeWeaver;
if (ltw == null) {
Assert.state(this.beanFactory != null,
"BeanFactory required if no LoadTimeWeaver explicitly specified");
ltw = this.beanFactory.getBean(
ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME, LoadTimeWeaver.class);
}
((LoadTimeWeaverAware) bean).setLoadTimeWeaver(ltw);
}
return bean;
}
//InitDestroyAnnotationBeanPostProcessor:处理声明周期注解方法的处理器。有了它,就允许用注解代替去实现Spring的接口InitializingBean和DisposableBean了。
//比如@PostConstruct和@PreDestroy等
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
metadata.invokeInitMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
}
return bean;
}
applyBeanPostProcessorsAfterInitialization的重要实现解释如下:
//ApplicationListenerDetector:把所有的ApplicationListener的Bean,都加入到addApplicationListener里面,放到广播器里面
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.remove(beanName);
}
}
return bean;
}
//BeanValidationPostProcessor:校验
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (this.afterInitialization) {
doValidate(bean);
}
return bean;
}
//ScheduledAnnotationBeanPostProcessor:解析方法中标注有@Scheduled注解的 然后加入当作一个任务进行执行
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) {
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
if (!this.nonAnnotatedClasses.contains(targetClass)) {
Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
(MethodIntrospector.MetadataLookup<Set<Scheduled>>) method -> {
Set<Scheduled> scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations(
method, Scheduled.class, Schedules.class);
return (!scheduledMethods.isEmpty() ? scheduledMethods : null);
});
if (annotatedMethods.isEmpty()) {
this.nonAnnotatedClasses.add(targetClass);
if (logger.isTraceEnabled()) {
logger.trace("No @Scheduled annotations found on bean class: " + bean.getClass());
}
}
else {
// Non-empty set of methods
annotatedMethods.forEach((method, scheduledMethods) ->
scheduledMethods.forEach(scheduled -> processScheduled(scheduled, method, bean)));
if (logger.isDebugEnabled()) {
logger.debug(annotatedMethods.size() + " @Scheduled methods processed on bean '" + beanName +
"': " + annotatedMethods);
}
}
}
return bean;
}
//SimpleServletPostProcessor:这个很有意思。 相当于当Servlet是以Bean的形式注入容器的时候,Bean初始化完成后,会自动调用它的init方法~~~~~~~~
//如果config为null,那么它传入可能为代理的DelegatingServletConfig
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof Servlet) {
ServletConfig config = this.servletConfig;
if (config == null || !this.useSharedServletConfig) {
config = new DelegatingServletConfig(beanName, this.servletContext);
}
try {
((Servlet) bean).init(config);
}
catch (ServletException ex) {
throw new BeanInitializationException("Servlet.init threw exception", ex);
}
}
return bean;
}
整个初始化流程如下:
- 调用各类感知Aware接口
- 执行applyBeanPostProcessorsBeforeInitialization初始化前的处置操作
- 调用InitializingBean接口初始化 (如果配置了method-init,则调用其方法初始化 )
- 调用applyBeanPostProcessorsAfterInitialization 初始化之后的处置操作
populateBean和initializeBean完成了我们Spring IOC容器的核心内容:依赖注入。前面做的都是准备工作,同时这里也调用了可以参与Bean生命周期的各种钩子方法。
总结
getBean()方法是Spring IOC容器实例化、初始化Bean的核心方法,里面的逻辑也异常的复杂。
一个优秀的框架,绝不仅仅是说可以通过反射能帮助创建Bean就行了,而是像Spring这样能够考虑到各式各样的情况,有非常好的容错性、有很好的异常处理以及提示调用者报错原因。当然也有一一系列的设计原则的体现:单一职责原则、面向对象的设计原则、对扩展开放对修改关闭的原则(BeanPostProcessor是个非常好的钩子,允许我们参与进Bean的声明周期中来)
参考: |