【Spring源码学习】Spring Bean实例化过程-创建Bean实例
- 前言
- Spring 初始化核心流程
- 一、Bean实例化流程
- 二、时序图
- 三、源码跟踪
- 1.finishBeanFactoryInitialization()
- 2.preInstantiateSingletons()
- 3.getBean(),doGetBean()
- 4.getSingleton()
- 5.createBean()
- 6.doCreateBean()
- 6.1.createBeanInstance()
- 6.1.1.构造函数的选取之determineConstructorsFromBeanPostProcessors()
- 6.1.2.构造函数的选取之autowireConstructor()
- 6.2.注解扫描applyMergedBeanDefinitionPostProcessors()
- 6.2.1.@PostConstruct,@PreDestroy和@Resource注解扫描
- 6.2.2.@Autowired和@Value注解扫描
前言
Spring 初始化核心流程
spring容器初始化的核心方法AbstractApplicationContext#refresh,
- refresh Spring 初始化核心流程入口
- prepareRefresh ① 准备此上下文用于刷新,设置启动时间和active标志,初始化属性
- obtainFreshBeanFactory ② 创建 BeanFactory 已经跟踪过的源码流程
- prepareBeanFactory ③ 设置 BeanFactory 的基本属性
- postProcessBeanFactory ④ 子类处理自定义的BeanFactoryPostProcess
- invokeBeanFactoryPostProcessors ⑤ 调用所有的BeanFactoryPostProcessor
- registerBeanPostProcessors ⑥ 注册,把实现了BeanPostProcessor接口的类实例化,加到BeanFactory
- initMessageSource ⑦ 初始化上下文中的资源文件,如国际化文件的处理等
- initApplicationEventMulticaster ⑧ 初始化上下文的事件传播器
- onRefresh ⑨ 给子类扩展初始化其他Bean,springboot 中用来做内嵌 tomcat 启动
- registerListeners ⑩ 在所有bean中查找监听 bean,然后注册到广播器中
- finishBeanFactoryInitialization ⑪ 本节主要跟踪的源码流程
- finishRefresh ⑫ 完成刷新过程,发布相应的事件
一、Bean实例化流程
总体上,Bean实例化流程主要有三个步骤:
- 创建Bean实例
- 属性注入
- Bean初始化
本章主要是讲创建Bean实例的过程,我分为两个部分:一是构造函数的选取,二是依赖注入相关的注解扫描.
二、时序图
三、源码跟踪
1.finishBeanFactoryInitialization()
点进去看看finishBeanFactoryInitialization()方法
/**
* 这个方法是spring中最重要的方法,没有之一
* 所以这个方法一定要理解要具体看
* 1、bean实例化过程
* 2、ioc
* 3、注解支持
* 4、BeanPostProcessor的执行
* 5、Aop的入口
* */
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
//设置类型转换器
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
//暂时不要看
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
//暂时不看
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
//重点看这个方法,重要程度:5
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
重点关注这个方法的处理beanFactory.preInstantiateSingletons()
2.preInstantiateSingletons()
/*
* 具体实例化过程
* */
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
//xml解析时,讲过,把所有beanName都缓存到beanDefinitionNames了
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
//把父BeanDefinition里面的属性拿到子BeanDefinition中
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//如果不是抽象的,单例的,非懒加载的就实例化
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//判断bean是否实现了FactoryBean接口,这里可以不看 &factoryBeanDemo
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
//主要从这里进入,看看实例化过程
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
3.getBean(),doGetBean()
这里不看factoryBean的实例化,我这里关注getBean(beanname)方法,另外先注意一下bean实例化的条件
- 不是抽象的
- 单例的
- 非懒加载的
//AbstractBeanFactory
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// 获取一个beanName,处理两种情况,一个是前面说的 FactoryBean (前面带 '&'),
// 一个是别名问题,因为这个方法是 getBean,获取 Bean 用的,你要是传一个别名进来,是完全可以的
String beanName = transformedBeanName(name);
Object bean;
/*
* Description : 检查缓存中或者实例工厂中是否有对应的实例
* 因为在创建单例 bean的时候会存在依赖注入,而在创建依赖的时候为了避免循环依赖,
* spring创建bean的原则是:不等 bean 创建完成就将创建bean的 ObjectFactory 提早曝光,
* 换句话说,也就是将 ObjectFactory 加入到缓存中,一旦下一个bean创建的时候需要依赖上
* 一个bean则直接使用 ObjectFactory
*
* 第一次getSingleton(beanName)
*/
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
//如果缓存里面能拿到实例
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 该方法是 FactoryBean 接口的调用入口
// 如果是普通 Bean 的话,直接返回 sharedInstance(直接返回对象本身)
// 如果是 FactoryBean 的话,返回它创建的那个实例对象(返回指定方法返回的实例)
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//如果singletonObjects缓存里面没有,则走下来
// Fail if we're already creating this bean instance:
// We're assembly within a circular reference.
//如果是scope 是Prototype的,校验是否有出现循环依赖,如果有则直接报错
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
//检查一下这个 BeanDefinition 在容器中是否存在
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 如果当前容器不存在这个 BeanDefinition,试试父容器中有没有
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// typeCheckOnly 为 false,将当前 beanName 放入一个 alreadyCreated 的 Set 集合中。
// 如果不是仅仅做类型检查而是创建bean,则进行记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
//要开始创建bean了,分两种情况:一种是针对单例的(singleton),一种是针对多例的(prototype),一种是自定义scope的
try {
//父子BeanDefinition合并
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//获取依赖对象属性,依赖对象要先实例化
// Guarantee initialization of beans that the current bean depends on.
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);
}
}
}
//单例情况singleton,着重看,大部分是单例的情况
// Create bean instance.
if (mbd.isSingleton()) {
//第二次getSingleton(beanName, singletonFactory)
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
//该方法是FactoryBean接口的调用入口
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//多例情况prototype
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);
}
//该方法是FactoryBean接口的调用入口
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 如果不是 singleton 和 prototype 的话,需要委托给相应的实现类来处理
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
// 最后,检查一下类型对不对,不对的话就抛异常,对的话就返回
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
4.getSingleton()
我们先看看两次调用getSingleton()的两个重载方法
第一次调用
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//根据beanName从缓存中拿实例
//先从一级缓存拿
Object singletonObject = this.singletonObjects.get(beanName);
//如果bean还正在创建,还没创建完成,其实就是堆内存有了,属性还没有DI依赖注入
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//从二级缓存中拿
singletonObject = this.earlySingletonObjects.get(beanName);
//如果还拿不到,并且允许bean提前暴露
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;
}
这次的调用缓存里都是没有的,三级缓存的设计是为了解决循环依赖和AOP代理的问题,这个在后面详说。
第二次调用
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
//如果缓存中有,则直接返回
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
//把beanName添加到singletonsCurrentlyInCreation Set容器中,在这个集合里面的bean都是正在实例化的bean
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
//如果这里有返回值,就代表这个bean已经结束创建了,已经完全创建成功
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//bean创建完成后singletonsCurrentlyInCreation要删除该bean
afterSingletonCreation(beanName);
}
if (newSingleton) {
//创建对象成功时,把对象缓存到singletonObjects缓存中,bean创建完成时放入一级缓存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
这里总结一下流程
- 把beanName添加到singletonsCurrentlyInCreation Set容器中(其中这个在循环依赖时三级缓存会用到)
- singletonFactory.getObject():这个就会调用到外层Lambda表达式中实现getObject()的业务方法,即createBean()方法,就是这个
() -> {
try {
return createBean(beanName, mbd, args);
}
......此处省略一万字的代码。^_^
- bean创建成功(完整的bean),从singletonsCurrentlyInCreation删除
- 将bean添加至一级缓存中
5.createBean()
好,进去看看createBean方法
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 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.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
/*
* TargetSource接口的运用,可以在用改一个类实现该接口,然后在里面定义实例化对象的方式,然后返回
* 也就是说不需要spring帮助我们实例化对象
*
*
* 这里可以直接返回实例本身
*
* 这个代码不用看,实际开发过程中用不到,我会做为一个甜点分享
* */
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
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 {
//主要看这个方法,重要程度 5
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
关键看doCreateBean()
6.doCreateBean()
/**
* Description: 创建bean实例的核心方法
*/
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建实例,,重点看,重要程度:5
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//CommonAnnotationBeanPostProcessor 支持了@PostConstruct,@PreDestroy,@Resource注解
//AutowiredAnnotationBeanPostProcessor 支持 @Autowired,@Value注解
//BeanPostProcessor接口的典型运用,这里要理解这个接口
//对类中注解的装配过程
//重要程度5,必须看
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提前暴露
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//这里着重理解,对理解循环依赖帮助非常大,重要程度 5 添加三级缓存
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//ioc di,依赖注入的核心方法,该方法必须看,重要程度:5
populateBean(beanName, mbd, instanceWrapper);
//bean 实例化+ioc依赖注入完以后的调用,非常重要,重要程度:5
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//注册bean销毁时的类DisposableBeanAdapter
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
这个方法就是核心创建bean的。
一个个来,先看创建一个原始的实例方法createBeanInstance()
6.1.createBeanInstance()
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 1. 得到bean的class,并验证class的访问权限是不是public
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//如果有FactoryMethodName属性 @Bean
if (mbd.getFactoryMethodName() != null) {
// 反射的方式调用FactoryMethod
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
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);
}
}
// Candidate constructors for autowiring?
//寻找当前正在实例化的bean中有@Autowired注解的构造函数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
//第一次推断构造函数
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//如果ctors不为空,就说明构造函数上有@Autowired注解
//第二次推断构造函数
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
//如果首选的构造器不为空, 则使用首选的构造器进行实例化,以及进行以来注入
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
//无参构造函数的实例化,大部分的实例是采用的无参构造函数的方式实例化
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
就是干一件事,用哪种构造函数来创建实例
- 如果bean配置了factory-method,则反射实例化一个对象
- 如果没有配置factory-method,并且曾经创建过,那就按照原来的方式再创建
- 上述两种情况都不是,则先去当前正在实例化的bean中查出有@Autowired注解的构造函数,而这个动作是交给AutowiredAnnotationBeanPostProcessor中的determineCandidateConstructors方法来完成的
- 如果上述扫描出来的有@Autowired注解的构造函数不为空,则选择autowireConstructor来进行
- 如果首选的构造器不为空, 则使用首选的构造器进行实例化,以及进行依赖注入
- 否则,无参构造函数实例化
点进去看看determineConstructorsFromBeanPostProcessors()
6.1.1.构造函数的选取之determineConstructorsFromBeanPostProcessors()
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
// 拿到 BeanPostProcessor 的所有接口,遍历
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 获取到有@Autowired注解信息的构造函数
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
其中,
- getBeanPostProcessors()方法,获取所有BeanPostProcessor接口,是AbstractBeanFactory类中的一个List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>()容器,装载了上下文中所有的BeanPostProcessor类的实例。
- SmartInstantiationAwareBeanPostProcessor类中的determineCandidateConstructors方法,会调用其子类 AutowiredAnnotationBeanPostProcessor 中的determineCandidateConstructors方法,来获取到有@Autowired注解信息的构造函数。AutowiredAnnotationBeanPostProcessor类会完成@Autowired和@value两个注解的扫描。
- AutowiredAnnotationBeanPostProcessor 中的determineCandidateConstructors方法返回构造方法数组,以下两种情况返回值不为null:
- 有且仅有一个带参构造方法,返回那个构造方法
- 有多个@Autowired(required = false)注解的构造方法,返回这些构造方法
去看看AutowiredAnnotationBeanPostProcessor 中的determineCandidateConstructors方法
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// 在实例化某个对象的过程中会调用这个方法,得到候选构造方法
// Let's check for lookup methods here...
if (!this.lookupMethodsChecked.contains(beanName)) {
if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
try {
Class<?> targetClass = beanClass;
do {
// 遍历当前beanClass中所有加了Lookup注解的方法,并且把这些方法的信息封装为LookupOverride对象加载mbd中
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//对注解Lookup的支持
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition)
this.beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
}
// lookupMethodsChecked是一个set,用来记录哪些bean的@lookup注解被解析了,下一次就不用解析了
this.lookupMethodsChecked.add(beanName);
}
// 先检查candidateConstructorsCache中是否缓存了当前bean中可用的构造方法
// 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 {
// 拿到当前类所有的构造方法,如果没有写任何构造方法,这里会返回一个无参的构造方法
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);
}
// candidates 就是用来存储所有被筛选出来的构造方法,其实可以认为, 就是把所有@Autowired注解标注的方法放到里面,
// 但是还多放了一个默认构造方法
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
// requiredConstructor表示@Autowired标注并且required为true的构造方法, 因为只允许出现一个这样的构造方法,
//所以当这个变量存在值后, 又出现了一个相同情况的构造方法的话, Spring就会抛出一个错误
Constructor<?> requiredConstructor = null;
// defaultConstructor用来保存默认构造方法
Constructor<?> defaultConstructor = null;
// 如果是kotlin的类才起效,如果是java中的类则直接返回null
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
// 遍历所有的构造方法
for (Constructor<?> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
// 查看该构造方法上是否存在@Autowired注解,或者看代理类的父类中对应的构造方法上是否存在@Autowired注解
//获取到构造函数上的@Autowired注解信息,这个方法可以不看
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
if (ann == null) {
// 如果当前类是cglib生成的代理类,则获取其父类
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor<?> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
// 如果构造方法上存在@Autowired注解
if (ann != null) {
// requiredConstructor表示程序员手动指明的要使用的哪个构造方法
// 所以如果有多个构造方法上都写了@Autowired注解就会报错,required位true的情况下
// 因为作为程序员你如果告诉Spring多个构造方法,那Spring也就不知道到底要使用哪一个了
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
//获取到@Autowired里面的required的值,默认 true
boolean required = determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
requiredConstructor = candidate;
}
// candidates中存的是加了@Autowired注解的构造方法
candidates.add(candidate);
}
// 如果当前构造方法上不存在@Autowired,并且是无参构造方法,则记录一下该无参构造方法
// 所以我们可以在遍历构造方法时,只关心无参构造方法和加了@Autowired注解的构造方法
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
// 如果存在添加了@Autowired的构造方法
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
// 分为两种请求,要么candidates中包含一个required等于true的构造方法
// 要么candidates中包含一个或多个required等于false的构造方法
// 如果没有指定required为true的构造方法,那么就把构造方法添加到candidates中去,后续一起进行推断
if (requiredConstructor == null) {
if (defaultConstructor != null) {
// 把无参的构造方法也添加进去
candidates.add(defaultConstructor);
}
// 如果没有指定required为true的构造方法,并且也没有无参的构造方法,并且只有一个构造方法
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
// 给一个提示,没有无参的构造方法,然后又只有一个@Autowired(required=false)的构造方法
// 所以其实一定会用这个构造方法,所以打印一个日志,告诉程序员,你其实可以把required改为true
logger.info("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方法,两种情况,要么只有一个@Autowired(required=true)的构造方法,要么多个@Autowired(required=false)+一个无参构造方法
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
// 没有加了@Autowired注解的构造方法,那么则判断是不是只有一个有参的构造方法,如果是则返回
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
// primaryConstructor != null 不管
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};
}
// 如果没有构造方法上添加了@Autowired注解,并且有多个构造方法,并且没有primaryConstructor
else {
// 返回一个空的Constructor数组,表示没有推断出来构造方法
candidateConstructors = new Constructor<?>[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
// 要么返回一个required=true的构造方法
// 要么返回多个required=false+无参的构造方法
// 要么返回唯一的一个有参的构造方法
// 如果只有一个无参的构造方法,这里会返回null,外层逻辑会默认使用无参构造方法进行实例化
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
这个方法执行完毕后,我们就可以进行第一次推断构造函数了,回到6.1.createBeanInstance()中的determineConstructorsFromBeanPostProcessors。我们再看看第二次推断构造函数的过程
6.1.2.构造函数的选取之autowireConstructor()
调用的为ConstructorResolver的autowireConstructor()
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
点进去autowireConstructor,参考这位大神画的流程spring源码解析(四) 推断构造方法
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
// 是否通过getBean()方法指定了构造方法参数值
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
// 从缓存中获取构造方法和构造方法参数值
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
// 找到了mbd中缓存的构造方法
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果存在构造方法参数值,那么则对参数值进行类型转化
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
// 如果待使用的构造方法为null,或待使用的构造方法参数为null
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
// chosenCtors表示所指定的构造方法,没有指定则获取beanClass中的所有的构造方法作为候选者,从这些构造方法中选择一个构造方法
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
// 有了构造方法之后,则进行自动推断
// 如果只有一个构造方法,并且没有指定构造方法参数值,则需要判断是不是无参构造方法,如果是则可以使用无参构造方法进行实例化
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
// 确定了构造方法之后进行缓存
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// 如果指定了多个构造方法,或者autowireMode是构造方法自动注入,则要自动选择构造方法
// Need to resolve the constructor.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
// 表示所有构造方法中,参数个数最少的构造方法的参数个数是多少
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// 从BeanDefinition中获取所设置的构造方法参数值
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
// 记录解析后的构造方法参数值
resolvedValues = new ConstructorArgumentValues();
// 解析BeanDefinition中所设置的构造方法参数值(index跳跃)
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 按构造方法的参数个数降序排序,参数个数多的在前
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
// 遍历构造方法,找到一个最合适的(贪婪)
// 先看参数列表最长的构造方法,根据每个参数的参数类型和参数名去找bean
for (Constructor<?> candidate : candidates) {
// 当前构造方法的参数个数
int parameterCount = candidate.getParameterCount();
//如果之前的构造器已经有一个被处理过且该参数个数大于当前遍历的,则后面的构造器就不用处理了
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
// 在遍历某个构造方法时,如果参数个数小于用于所指定的参数个数,则忽略该构造方法
if (parameterCount < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
// 当前遍历到的某个构造方法的参数类型
Class<?>[] paramTypes = candidate.getParameterTypes();
// 没有通过getBean()方法指定构造方法参数值
if (resolvedValues != null) {
try {
// 获取参数名
// 查看是否在构造方法上使用@ConstructorProperties注解来定义构造方法参数的名字
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
//这里会触发构造函数中参数的getBean操作,会实例化参数的值
// 根据当前构造方法的参数类型和参数名从beanFactory中得到bean作为参数值
// resolvedValues, 表示所指定的构造方法参数值
// paramTypes,当前构造方法的参数类型列表
// paramNames,当前构造方法的参数值列表
// getUserDeclaredConstructor(candidate)获取父类中被重写的构造方法
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
// 如果找不到对应的bean,也不会直接报错,只能证明当前遍历到的构造方法不能用
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
else {
// 通过getBean()方法指定了构造方法参数值
// Explicit arguments given -> arguments length must match exactly.
if (parameterCount != explicitArgs.length) {
continue;
}
// 如果参数个数匹配,则把所有参数值封装为一个ArgumentsHolder对象
argsHolder = new ArgumentsHolder(explicitArgs);
}
// 执行到这里,表示当前构造方法可用,并且也找到了对应的构造方法参数值
// 但是还需要判断,当前构造方法是不是最合适的,也许还有另外的构造方法更合适
// 根据参数类型和参数值计算权重
// Lenient宽松,默认宽松模式是开启的
// 在宽松模式下,会判断每个参数值的类型和当前构造方法的参数类型的距离
// 在非宽松模式下,会忽略每个参数值的类型和当前构造方法的参数类型的距离,只要是父子关系距离是一样的
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 如果当前构造方法的权重比较小,则表示当前构造方法更合适,将当前构造方法和所找到参数值作为待使用的,遍历下一个构造方法
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
// 如果权重一样,则记录在ambiguousConstructors中,继续遍历下一个构造方法
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}//end of for
// 遍历完所有构造方法后,没有找到合适的构造方法,则报错
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)");
}
// 如果存在权重一样的构造方法并且不是宽松模式,也报错,因为权重一样,Spring不知道该用哪个
// 如果是宽松模式则不会报错,Spring会用找到的第一个
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);
}
// 如果不是通过getBean()方法指定的参数,那么就把找到的构造方法参数进行缓存
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
// 得到了构造方法和构造方法的参数值之后,就可以进行实例化了
Assert.state(argsToUse != null, "Unresolved constructor arguments");
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
总结下:
- 手动装配
- 没有显式提供构造方法:使用默认构造方法
- 提供一个构造方法:使用该构造方法
- 提供多个构造方法,包含默认构造方法:使用默认构造方法
- 提供多个构造方法,不包含默认构造方法:报错
- 提供多个构造方法,有一个@Autowired(required = true)的构造方法:使用有@Autowired(required = true)的构造方法
- 提供多个构造方法,有多个@Autowired(required = true)的构造方法:报错
- 提供多个构造方法,有一个@Autowired(required = true)的构造方法和多个@Autowired(required = false)的构造方法:报错
- 提供多个构造方法,有多个@Autowired(required = false)的构造方法:使用符合条件的&参数最多的构造方法
- 使用构造方法自动装配:使用符合条件的&参数最多的构造方法
如果两次推断构造函数均未果,则使用无参构造函数的实例化,大部分的实例是采用的无参构造函数的方式实例化,这里不继续跟了。回到6.doCreateBean(),再去看看applyMergedBeanDefinitionPostProcessors
6.2.注解扫描applyMergedBeanDefinitionPostProcessors()
这个方法主要功能为:收集@Resource、@PostConstruct、@PreDestory、@Autowired 和@Value注解的方法或属性,封装成对应的对象,方便后续依赖注入时使用。其中
- CommonAnnotationBeanPostProcessor 支持@PostConstruct,@PreDestroy和@Resource注解
- AutowiredAnnotationBeanPostProcessor 支持@Autowired和@Value注解
这两个类都是MergedBeanDefinitionPostProcessor的实现类。我们先点进去看看applyMergedBeanDefinitionPostProcessors()方法
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
//从所有BeanPostProcessor中过滤出MergedBeanDefinitionPostProcessor的类,循环扫描
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
我们先看看CommonAnnotationBeanPostProcessor的postProcessMergedBeanDefinition()方法
6.2.1.@PostConstruct,@PreDestroy和@Resource注解扫描
CommonAnnotationBeanPostProcessor的postProcessMergedBeanDefinition()
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//1.扫描@PostConstruct,@PreDestroy
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
//2.@Resource注解的属性或者方法的收集
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
分成两步完成相应注解的扫描:
- 收集被@PostConstruct 和@PreDestroy 注解标注的方法
1)CommonAnnotationBeanPostProcessor的构造函数先设置需要扫描的注解类型,再去父类InitDestroyAnnotationBeanPostProcessor中去扫描
public CommonAnnotationBeanPostProcessor() {
setOrder(Ordered.LOWEST_PRECEDENCE - 3);
//在此处进行设置,到父类中去获取标记了这些注解的类
setInitAnnotationType(PostConstruct.class);
setDestroyAnnotationType(PreDestroy.class);
ignoreResourceType("javax.xml.ws.WebServiceContext");
}
2)先看缓存中是否有,没有则重新去扫描
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
metadata.checkConfigMembers(beanDefinition);
}
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
if (this.lifecycleMetadataCache == null) {
// 缓存没有
return buildLifecycleMetadata(clazz);
}
// Quick check on the concurrent map first, with minimal locking.
LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
synchronized (this.lifecycleMetadataCache) {
metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
metadata = buildLifecycleMetadata(clazz);
this.lifecycleMetadataCache.put(clazz, metadata);
}
return metadata;
}
}
return metadata;
}
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
return this.emptyLifecycleMetadata;
}
//@PostConstruct 标记的方法
List<LifecycleElement> initMethods = new ArrayList<>();
//@PreDestroy 标记的方法
List<LifecycleElement> destroyMethods = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<LifecycleElement> currInitMethods = new ArrayList<>();
final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
//循环遍历类中所有的初始化和销毁的方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//收集@PostConstruct 标记的方法
if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
LifecycleElement element = new LifecycleElement(method);
currInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
}
}
//收集@PreDestroy 标记的方法
if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
currDestroyMethods.add(new LifecycleElement(method));
if (logger.isTraceEnabled()) {
logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
}
}
});
initMethods.addAll(0, currInitMethods);
destroyMethods.addAll(currDestroyMethods);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
new LifecycleMetadata(clazz, initMethods, destroyMethods));
}
- 收集被@Resource 注解的标注的方法和属性
1)先看缓存中是否有InjectionMetadata
private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
//缓存中不存在
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
metadata = buildResourceMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
2)分别获取被@Resource注解的属性和方法(这里我们只关注@Resource注解的属性和方法)
3)最终把两个field 和Method 封装的对象集合封装到InjectionMetadata 对象中
6.2.2.@Autowired和@Value注解扫描
AutowiredAnnotationBeanPostProcessor的postProcessMergedBeanDefinition()
AutowiredAnnotationBeanPostProcessor 类是对@Autowired 和@Value 注解的属性和方法的收集,收集
支持的注解类型可以在构造函数或者Static 静态块中找。收集过程基本上跟@Resource 注解的收集差不多。
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
收集过程跟上述@Resource 收集,调用的都是ReflectionUtils工具类中的方法,也是收集Field 和Method 上面的注解,然后放到InjectionMetadata对象中。