• bean的创建(五)第四部分 bean构造器的查找


    前面分析了bean的静态工厂查找
    bean的构造器查找过程和bean的静态工厂查找类似
    
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
            // Make sure bean class is actually resolved at this point.
            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());
            }
    
            if (mbd.getFactoryMethodName() != null)  {
    //使用工厂方法获取
                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);
                }
            }
    
            // Need to determine the constructor...通过后置处理器返回构造器,然后通过autowireConstructor去筛选构造器,这种可用于配置文件中没有配置构造器参数的方式。
            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);
        }
    
    
    AbstractAutowireCapableBeanFactory.autowireConstructor
    
    protected BeanWrapper autowireConstructor(
                String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) {
    
            return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
        }
    
    
    
    ConstructorResolver.autowireConstructor
    
    //beanName表示正在创建bean的名字,mbd表示正在创建bean的BeanDefinition,chosenCtors表示是程序指定的可选构造器列表,可通过后置处理器得到,explicitArgs是用户指定的构造参数
    public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
                Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
    
            BeanWrapperImpl bw = new BeanWrapperImpl();
    //初始化,注册类型转化器和自定义类型转化器
            this.beanFactory.initBeanWrapper(bw);
    
            Constructor<?> constructorToUse = null;
            ArgumentsHolder argsHolderToUse = null;
            Object[] argsToUse = null;
    
            if (explicitArgs != null) {
                argsToUse = explicitArgs;
            }
            else {
    //这里的操作和解析工厂方法时一样的
                Object[] argsToResolve = null;
                synchronized (mbd.constructorArgumentLock) {
    //从缓存中获取
                    constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
                    if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                        // Found a cached constructor...
                        argsToUse = mbd.resolvedConstructorArguments;
                        if (argsToUse == null) {
    //使用预备的集合参数
                            argsToResolve = mbd.preparedConstructorArguments;
                        }
                    }
                }
                if (argsToResolve != null) {
    //解析预备参数集合
                    argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
                }
            }
    
    //如果没有缓存,那么就从头开始查找
            if (constructorToUse == null) {
                // Need to resolve the constructor.
    //如果用户指定了构造器,或者装配为构造器自动装配
                boolean autowiring = (chosenCtors != null ||
                        mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
                ConstructorArgumentValues resolvedValues = null;
    
                int minNrOfArgs;
                if (explicitArgs != null) {
                    minNrOfArgs = explicitArgs.length;
                }
                else {
                    ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
                    resolvedValues = new ConstructorArgumentValues();
    //解析配置的参数
                    minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
                }
    
                // Take specified constructors, if any.
                Constructor<?>[] candidates = chosenCtors;
                if (candidates == null) {
    
                    Class<?> beanClass = mbd.getBeanClass();
                    try {
    //如果没有指定构造器,那么就获取当前bean的构造器
                        candidates = (mbd.isNonPublicAccessAllowed() ?
                                beanClass.getDeclaredConstructors() : beanClass.getConstructors());
                    }
                    catch (Throwable ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                                        "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
                    }
                }
    //进行排序,public在前,参数长的在前
                AutowireUtils.sortConstructors(candidates);
                int minTypeDiffWeight = Integer.MAX_VALUE;
                Set<Constructor<?>> ambiguousConstructors = null;
                LinkedList<UnsatisfiedDependencyException> causes = null;
    
                for (int i = 0; i < candidates.length; i++) {
                    Constructor<?> candidate = candidates[i];
                    Class<?>[] paramTypes = candidate.getParameterTypes();
    
                    if (constructorToUse != null && argsToUse.length > paramTypes.length) {
                        // Already found greedy constructor that can be satisfied ->
                        // do not look any further, there are only less greedy constructors left.
                        break;
                    }
                    if (paramTypes.length < minNrOfArgs) {
                        continue;
                    }
    
                    ArgumentsHolder argsHolder;
                    if (resolvedValues != null) {
                        try {
                            String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
                            if (paramNames == null) {
                                ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                                if (pnd != null) {
                                    paramNames = pnd.getParameterNames(candidate);
                                }
                            }
                            argsHolder = createArgumentArray(
                                    beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
                        }
                        catch (UnsatisfiedDependencyException ex) {
                            if (this.beanFactory.logger.isTraceEnabled()) {
                                this.beanFactory.logger.trace(
                                        "Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
                            }
                            // Swallow and try next constructor.
                            if (causes == null) {
                                causes = new LinkedList<UnsatisfiedDependencyException>();
                            }
                            causes.add(ex);
                            continue;
                        }
                    }
                    else {
                        // Explicit arguments given -> arguments length must match exactly.
                        if (paramTypes.length != explicitArgs.length) {
                            continue;
                        }
                        argsHolder = new ArgumentsHolder(explicitArgs);
                    }
    //根据一些宽松或者严格模式去寻找更适合的构造器
                    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) {
                        if (ambiguousConstructors == null) {
                            ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
                            ambiguousConstructors.add(constructorToUse);
                        }
    //存储存在歧义的构造器
                        ambiguousConstructors.add(candidate);
                    }
                }
    
                if (constructorToUse == null) {
                    if (causes != null) {
                        UnsatisfiedDependencyException ex = causes.removeLast();
                        for (Exception cause : causes) {
                            this.beanFactory.onSuppressedException(cause);
                        }
                        throw ex;
                    }
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Could not resolve matching constructor " +
                            "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
                }
                else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Ambiguous constructor matches found in bean '" + beanName + "' " +
                            "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
                            ambiguousConstructors);
                }
    
                if (explicitArgs == null) {
                    argsHolderToUse.storeCache(mbd, constructorToUse);
                }
            }
    
            try {
                Object beanInstance;
    
                if (System.getSecurityManager() != null) {
                    final Constructor<?> ctorToUse = constructorToUse;
                    final Object[] argumentsToUse = argsToUse;
                    beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        @Override
                        public Object run() {
                            return beanFactory.getInstantiationStrategy().instantiate(
                                    mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
                        }
                    }, beanFactory.getAccessControlContext());
                }
                else {
    //构造对应的bean实例
                    beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
                            mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
                }
    
                bw.setWrappedInstance(beanInstance);
                return bw;
            }
            catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Bean instantiation via constructor failed", ex);
            }
        }
  • 相关阅读:
    Ajax-ajax实例2-根据邮政编码获取地区信息
    javascript-限制文本框只输入数字
    Ajax-ajax实例1-动态加载的 FAQ
    Ajax-java中的ajax使用,以及编码问题
    java-request与response编码问题
    XMLHttpRequest对象的常用属性与方法
    Ajax类
    java-servlet 新增特性 注释
    java-servlet的url-pattern匹配规则详细描述
    java-过滤器Filter_多个Filter的执行顺序
  • 原文地址:https://www.cnblogs.com/honger/p/10389859.html
Copyright © 2020-2023  润新知