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; } }
内部类:BeanPostProcessorCheckersh实现了postProcessAfterInitialization方法:输出了一行日志而已
ApplicationListenerDetector重点实现了postProcessAfterInitialization方法:测那些实现了接口ApplicationListener的bean,在它们创建时初始化之后,将它们添加到应用上下文的事件多播器上。并在这些ApplicationListener bean销毁之前,将它们从应用上下文的事件多播器上移除。
子接口:SmartInstantiationAwareBeanPostProcessor
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
等等这种类,具体我们在AOP分析的时候再详解
子类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属性的操作,我们熟知的主要有下面这些工具类:
1.Apache的BeanUtils和PropertyUtils
2.cglib的BeanMap和BeanCopier
3.spring的BeanUtils
Spring中BeanWrapper 的主要在于如下三点:
1· 支持设置嵌套属性
2. 支持属性值的类型转换(设置ConversionService)
3. 提供分析和操作标准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提供的唯一实现类。具体此处不深究了,知道它是Spring用来统一处理Bean的就成了
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); }