深夜敲代码 潜水
  • 5发帖数
  • 5主题数
  • 0关注数
  • 0粉丝
开启左侧

发起收藏!spring源码剖析(万字长文)

[复制链接]
深夜敲代码 发表于 2021-8-9 13:00:07 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
在之前的文章里面已经介绍:spring在bean扫描过程,已经将所有的bean保存在一个beanDefinitionMap的map对象中,但是这些bean还是一个beanDefinition,还没进行实例化的,所以这次就重点解析bean的实例化过程。

  • finishBeanFactoryInitialization(beanFactory);
  • 合并父类,RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 举个例子说明一下,不怎么紧张:
                public class PcBd {        private String name;        public void setName(String name) {                this.name = name;        }        public void test() {                System.out.println(this.name);        }}public class test{        public static void main(String[] args) {                AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();                ac.register(Appconfig.class);                ac.refresh();                PcBd parentBd = (PcBd) ac.getBean("parentBd");                parentBd.test();                PcBd childBd = (PcBd) ac.getBean("childBd");                childBd.test();        }}// 输出:parentchildren上面的代码,主要是实现bean实例化的准备过程,从beanDefinitionNames中拿到被扫描出来的所有beanName。 然后遍历beanDefinitionNames,一个一个地调用getBean()方法,实例化这些bean对象。

  • getBean(beanName)
  • isSingletonCurrentlyInCreation 以为还没有必要创建对象的时候。
spring自动装配的模子 不等于 自动装配的技术。
no 会使用 bytype技术 bean的默认自动装配模子 == no public class OrderService{ IndexService indexService; } 这个indexService,直接忽略了装配 public class OrderService{ @Autowired IndexService indexService; } 这个indexService会先使用bytype技术自动装配,找不到再使用byname自动装配 复制代码

  • 下面进入到doGetBean()进行分析
protected  T doGetBean(final String name, @Nullable final Class requiredType,                        @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {        /**         * 通过 name 获取 beanName。这里不使用 name 直接作为 beanName 有两个原因         * 1、name 可能会以 & 字符开头,表明调用者想获取 FactoryBean 自己,而非 FactoryBean         *   实现类所创建的 bean。在 BeanFactory 中,FactoryBean 的实现类和其他的 bean 存储         *   方式是同等的,即 ,beanName 中是没有 & 这个字符的。所以我们必要         *   将 name 的首字符 & 移除,如许才能从缓存里取到 FactoryBean 实例。         * 2、还是别名的问题,转换必要         */        final String beanName = transformedBeanName(name);        Object bean;        /**         * 这个方法在初始化的时候会调用,在getBean的时候也会调用         * 为什么必要这么做呢?         * 也就是说spring在初始化的时候先获取这个对象         * 判定这个对象是否被实例化好了(普通情况下绝对为空====有一种情况可能不为空lazy=true,第二次调用)         * 从spring的bean容器中获取一个bean,由于spring中bean容器是一个map(singletonObjects)         * 所以你可以明白getSingleton(beanName)等于beanMap.get(beanName)         * 由于方法会在spring情况初始化的时候(就是对象被创建的时候调用一次)调用一次         * 还会在getBean的时候调用一次         * 所以再调试的时候必要特别注意,不能直接断点在这里,         * 必要先辈入到annotationConfigApplicationContext.getBean(IndexDao.class)         * 之后再来断点,如许就确保了我们是在获取这个bean的时候调用的         *         * 必要说明的是在初始化时候调用一样平常都是返回null         *         * 第一次调用:isSingletonCurrentlyInCreation以为还没到开始创建对象的时候         */        Object sharedInstance = getSingleton(beanName);        if (sharedInstance != null && args == null) {                // 这里的代码是对于日志的记录,方便我们以后阅读应该解释,不影响spring功能                 if (logger.isDebugEnabled()) {                         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 + "'");                         }                 }                /**                 * 假如 sharedInstance 是普通的单例 bean,下面的方法会直接返回。但假如                 * sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的                 * bean 实例。假如用户想获取 FactoryBean 自己,这里也不会做特别的处理,直接返回                 * 即可。毕竟 FactoryBean 的实现类自己也是一种 bean,只不过具有一点特别的功能而已。                 */                bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);        }        else {                // Fail if we're already creating this bean instance:                // We're assumably within a circular reference.                /**                 * 原型,判定当前正在创建的bean是不是原型。                 * 假如是原型不应该在初始化的时候创建                 */                if (isPrototypeCurrentlyInCreation(beanName)) {                        throw new BeanCurrentlyInCreationException(beanName);                }                // Check if bean definition exists in this factory. 父工厂                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);                        }                }                if (!typeCheckOnly) {                        //添加到alreadyCreated set集合当中,表示他已经创建过一场                        markBeanAsCreated(beanName);                }                try {                        final 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);                                        }                                }                        }                        // 创建单例的bean                        if (mbd.isSingleton()) {                                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;                                        }                                });                                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.        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;}

  • createBean(beanName, mbd, args); 分析
@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)                throws BeanCreationException {        if (logger.isDebugEnabled()) {                logger.debug("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.        // 处理 lookup-method 和 replace-method 设置,Spring 将这两个设置统称为 override method        try {                mbdToUse.prepareMethodOverrides();        }        catch (BeanDefinitionValidationException ex) {                throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),                                beanName, "Validation of method overrides failed", ex);        }        try {                // 在 bean 初始化前应用后置处理,假如后置处理返回的 bean 不为空,则直接返回                // 这个类必要通过代码演示                // 这个主要的作用是,将bean的所有依赖去到,直接返回一个寡对象。实现InstantiationAwareBeanPostProcessor接口。                // 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 {                // 调用doCreateBean 创建bean                Object beanInstance = doCreateBean(beanName, mbdToUse, args);                if (logger.isDebugEnabled()) {                        logger.debug("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);        }}

  • Object beanInstance = doCreateBean(beanName, mbdToUse, args); 分析
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)                        throws BeanCreationException {        // Instantiate the bean. 包装类        BeanWrapper instanceWrapper = null;        if (mbd.isSingleton()) {                instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);        }        if (instanceWrapper == null) {                /**                 * 创建 bean 实例,并将实例包裹在 BeanWrapper 实现类对象中返回。                 * createBeanInstance中包罗三种创建 bean 实例的方式:                 *   1. 通过工厂方法创建 bean 实例                 *   2. 通过构造方法自动注入(autowire by constructor)的方式创建 bean 实例                 *   3. 通过无参构造方法方法创建 bean 实例                 *                 * 若 bean 的设置信息中设置了 lookup-method 和 replace-method,则会使用 CGLIB                 * 增强 bean 实例。关于lookup-method和replace-method后面再说。                 */                instanceWrapper = createBeanInstance(beanName, mbd, args);        }        //拿到包装类的原生对象        final Object bean = instanceWrapper.getWrappedInstance();        Class beanType = instanceWrapper.getWrappedClass();        if (beanType != NullBean.class) {                mbd.resolvedTargetType = beanType;        }        // Allow post-processors to modify the merged bean definition.        synchronized (mbd.postProcessingLock) {                if (!mbd.postProcessed) {                        try {                                //非常紧张                                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);                        }                        catch (Throwable ex) {                                throw new BeanCreationException(mbd.getResourceDescription(), beanName,                                                "Post-processing of merged bean definition failed", ex);                        }                        mbd.postProcessed = true;                }        }        // Eagerly cache singletons to be able to resolve circular references        // even when triggered by lifecycle interfaces like BeanFactoryAware.        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");                }                addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));        }        // Initialize the bean instance.        Object exposedObject = bean;        try {                //设置属性,非常紧张                populateBean(beanName, mbd, instanceWrapper);                //实行后置处理器,aop就是在这里完成的处理                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 actualDependentBeans = new LinkedHashSet(dependentBeans.length);                                for (String dependentBean : dependentBeans) {                                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {                                                actualDependentBeans.add(dependentBean);                                        }                                }                                if (!actualDependentBeans.isEmpty()) {                                        throw new BeanCurrentlyInCreationException(beanName,                                                        "Bean with name '" + beanName + "' has been injected into other beans [" +                                                        StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +                                                        "] in its raw version as part of a circular reference, but has eventually been " +                                                        "wrapped. This means that said other beans do not use the final version of the " +                                                        "bean. This is often the result of over-eager type matching - consider using " +                                                        "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");                                }                        }                }        }        // Register bean as disposable.        try {                registerDisposableBeanIfNecessary(beanName, bean, mbd);        }        catch (BeanDefinitionValidationException ex) {                throw new BeanCreationException(                                mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);        }        return exposedObject;}doCreateBean()方法主要的作用: 1.先利用反射技术生成bean的实例对象。createBeanInstance(beanName, mbd, args) 2.对实例对象的属性,进行自动装配。populateBean(beanName, mbd, instanceWrapper); 3.实行后置处理器,进行bean增强。 initializeBean(beanName, exposedObject, mbd);

  • createBeanInstance(beanName, mbd, args) 利用反射技术实例化对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {        // Make sure bean class is actually resolved at this point.        Class beanClass = resolveBeanClass(mbd, beanName);        /**         * 检测一个类的访问权限spring默认情况下对于非public的类是答应访问的。         */        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);        }        /**         *         * 假如工厂方法不为空,则通过工厂方法构建 bean 对象         * 这种构建 bean 的方式可以自己写个demo去试试         * 源码就不做深入分析了,有兴趣的同砚可以和我私下讨论         * 假如设置了factoryMethod,就使用FactoryMethod方法实例化对象。(举例子实现)         */        if (mbd.getFactoryMethodName() != null)  {                return instantiateUsingFactoryMethod(beanName, mbd, args);        }        // Shortcut when re-creating the same bean...        /**         * 从spring的原始解释可以知道这个是一个Shortcut,什么意思呢?快捷方式         * 当多次构建同一个 bean 时,可以使用这个Shortcut,         * 也就是说不在必要次推断应该使用哪种方式构造bean         * 比如在多次构建同一个prototype类型的 bean 时,就可以走此处的shortcut         * 这里的 resolved 和 mbd.constructorArgumentsResolved 将会在 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) {                        //通过构造方法自动装配的方式构造 bean 对象                        return autowireConstructor(beanName, mbd, null, null);                }                else {                        //通过默认的无参构造方法进行                        return instantiateBean(beanName, mbd);                }        }        //1.当有无参构造方法,就默认使用该无参构造方法,实例化对象。                //因为spring不知道,你是使用有参构造方法实例化对象,还是使用无参构造方法实例化对象,所以就简单一点,使用无参构造方法实例化对象。        //2.当且仅当只有一个有参构造方法,就使用该有参构造方法,实例化对象。                //当你有多个有参构造方法的时候,spring也是不知道该用哪个构造方法实例化对象,所以就简单一点,使用无参构造方法实例化对象。        //由后置处理器决定返回哪些构造方法        //拿到bean的构造方法,然后使用该构造方法实例化对象。(要用哪个构造方法实例化对象,交给BeanPostProcessors处理)        Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);        if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||                        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {                return autowireConstructor(beanName, mbd, ctors, args);        }        //使用默认的无参构造方法进行初始化        return instantiateBean(beanName, mbd);}createBeanInstance主要的步骤有: 1.判定bean是否可以访问。 2.判定bean是否有factory-method方法,假如有就调用factory-method方法实例化对象 3.判定bean是否是第二次实例化,并是否存在快捷方式实例化对象。 4.判定bean的构造方法:
1.当bean有无参构造方法,就默认使用该无参构造方法,实例化对象 2.当bean只有一个有参构造方法,就使用该有参构造方法,实例化对象 3.当bean有多个有参构造方法,使用无参构造方法,实例化对象。(spring无法判定要用哪个构造方法)
备注:spring是使用构造方法方式,实例化对象

  • determineConstructorsFromBeanPostProcessors() 用哪个构造方法实例化对象,交给BeanPostProcessors处理
protected Constructor[] determineConstructorsFromBeanPostProcessors(@Nullable Class beanClass, String beanName)                        throws BeansException {        if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {                for (BeanPostProcessor bp : getBeanPostProcessors()) {                        if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {                                SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;                                Constructor[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);                                if (ctors != null) {                                        return ctors;                                }                        }                }        }        return null;}#AutowiredAnnotationBeanPostProcessor//决定使用哪个候选的构造方法@Override@Nullablepublic Constructor[] determineCandidateConstructors(Class beanClass, final String beanName)                throws BeanCreationException {        // Let's check for lookup methods here..        if (!this.lookupMethodsChecked.contains(beanName)) {                try {                        ReflectionUtils.doWithMethods(beanClass, method -> {                                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");                                        }                                }                        });                }                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) {                                // 拿到bean的所有构造方法                                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);                                }                                List requiredConstructor = null;                                Constructor defaultConstructor = null;                                Constructor primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);                                int nonSyntheticConstructors = 0;                                for (Constructor candidate : rawCandidates) {                                        if (!candidate.isSynthetic()) {                                                //记录bean有多少个构造方法                                                nonSyntheticConstructors++;                                        }                                        else if (primaryConstructor != null) {                                                continue;                                        }                                        AnnotationAttributes ann = findAutowiredAnnotation(candidate);                                        if (ann == null) {                                                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...                                                        }                                                }                                        }                                        if (ann != null) {                                                if (requiredConstructor != null) {                                                        throw new BeanCreationException(beanName,                                                                        "Invalid autowire-marked constructor: " + candidate +                                                                        ". Found constructor with 'required' Autowired annotation already: " +                                                                        requiredConstructor);                                                }                                                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.add(candidate);                                        }                                        //假如构造方法的没有参数,就是默认的构造方法。就使用该默认构造方法实例化对象。                                        else if (candidate.getParameterCount() == 0) {                                                defaultConstructor = candidate;                                        }                                }                                if (!candidates.isEmpty()) {                                        // Add default constructor to list of optional constructors, as fallback.                                        if (requiredConstructor == null) {                                                if (defaultConstructor != null) {                                                        candidates.add(defaultConstructor);                                                }                                                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]);                                }                                else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {                                        //只有一个有参构造方法,返回该有参构造方法                                        candidateConstructors = new Constructor[] {rawCandidates[0]};                                }                                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 {                                        //返null,纵然用默认无参构造方法实例化对象。                                        candidateConstructors = new Constructor[0];                                }                                this.candidateConstructorsCache.put(beanClass, candidateConstructors);                        }                }        }        return (candidateConstructors.length > 0 ? candidateConstructors : null);}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

猜你喜欢
在线客服邮箱
wxcy#wkgb.net

邮箱地址#换为@

Powered by 创意电子 ©2018-现在 专注资源实战分享源码下载站联盟商城