美文网首页
Spring4 Bean实例化源码

Spring4 Bean实例化源码

作者: sunpy | 来源:发表于2019-03-19 14:56 被阅读0次

    介绍

    Spring4的依赖注入的过程是先Bean实例化,然后进行属性的填充。而其中Bean的实例化的过程,可能会工厂方式实例化,也可能无参构造器实例化,也可能有参构造器实例化。而本篇文章主要针对Bean实例化,对于属性的填充放到下篇文章分析。

    Bean实例化开始位置

    AbstractAutowireCapableBeanFactory类之createBeanInstance方法

    // 使用适当的实例化策略为指定bean创建一个新实例
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
        // 检查确认Bean是可实例化的 
        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);
        }
    
        // 使用容器的自动装配方法进行实例化
        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);
            }
        }
    
            // 使用给定的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);
        }
    
        // 使用默认的无参构造方法实例化
        return instantiateBean(beanName, mbd);
    }
    

    说明:

    1. resolveBeanClass方法:解析Bean的class类,并将解析结果设置到BeanDefinition。
    2. instantiateUsingFactoryMethod方法:如果工厂方法不为空则使用factory-method工厂方法实例化。
    3. autowireConstructor方法:如果构造函数参数已经初始化,那么使用带参数构造函数实例化。
    4. instantiateBean方法:使用无参构造函数实例化。

    1. 工厂方式实例化,instantiateUsingFactoryMethod方法

    // 工厂方式实例化Bean
    protected BeanWrapper instantiateUsingFactoryMethod(
            String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
        // 初始化beanFactory
        // 使用命名工厂方法实例化bean
        return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
    }
    

    2. 有参构造器实例化,autowireConstructor方法

    // 带有参数的实例化
    protected BeanWrapper autowireConstructor(
            String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) {
        // 初始化beanFactory
        // 带有参数的实例化
        return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
    }
    
    // 根据指定的类型的参数,来匹配构造函数
    public BeanWrapper autowireConstructor(
            final String beanName, final RootBeanDefinition mbd, Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
        
        BeanWrapperImpl bw = new BeanWrapperImpl();
        // 调用将创建和填充bean实例的beanwrapper
        this.beanFactory.initBeanWrapper(bw);
        
        Constructor<?> constructorToUse = null;
        ArgumentsHolder argsHolderToUse = null;
        Object[] argsToUse = null;
        // 如果getBean方法调用的时候指定方法参数那么直接使用
        if (explicitArgs != null) {
            argsToUse = explicitArgs;
        }
        else {
            // 如果在getBean方法时候没有指定则尝试从配置文件中解析
            Object[] argsToResolve = null;
            // 尝试从缓存中获取
            synchronized (mbd.constructorArgumentLock) {
                // 获取已缓存解析的构造函数或工厂方法
                constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
                // 如果缓存不为空,并且构造参数已经解析缓存了
                if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                    // 从缓存中获取
                    argsToUse = mbd.resolvedConstructorArguments;
                    if (argsToUse == null) {
                        // 如果获取到的缓存的构造参数是空,就获取缓存的部分准备的构造函数参数
                        // preparedConstructorArguments:用于缓存部分准备的构造函数参数的包可见字段
                        argsToResolve = mbd.preparedConstructorArguments;
                    }
                }
            }
            // 如果缓存中参数不为空,那么就进行解析
            if (argsToResolve != null) {
                // 解析参数类型
                // 缓存中的值可能是原始值也可能是最终值
                argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
            }
        }
    
        // 如果缓存的构造器不存在,就说明没有bean进行过解析
        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 {
                    candidates = (mbd.isNonPublicAccessAllowed() ?
                            beanClass.getDeclaredConstructors() : beanClass.getConstructors());
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                                    "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
                }
            }
            // 排序给定的构造函数;public>protect>private;public构造函数优先参数数量降序
            AutowireUtils.sortConstructors(candidates);
            int minTypeDiffWeight = Integer.MAX_VALUE;
            Set<Constructor<?>> ambiguousConstructors = null;
            List<Exception> 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) {
                    // 如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数参数个数则终止
                    // 因为已经按照参数个数降序排序。
                    break;
                }
                if (paramTypes.length < minNrOfArgs) {
                    // 参数个数不相等
                    continue;
                }
    
                ArgumentsHolder argsHolder;
                if (resolvedValues != null) {
                    // 有参数则根据值构造对应参数类型的参数
                    try {
                        String[] paramNames = null;
                        if (constructorPropertiesAnnotationAvailable) {
                            // 注释上获取参数名称
                            paramNames = ConstructorPropertiesChecker.evaluateAnnotation(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);
                        }
                        if (i == candidates.length - 1 && constructorToUse == null) {
                            if (causes != null) {
                                for (Exception cause : causes) {
                                    this.beanFactory.onSuppressedException(cause);
                                }
                            }
                            throw ex;
                        }
                        else {
                            // Swallow and try next constructor.
                            if (causes == null) {
                                causes = new LinkedList<Exception>();
                            }
                            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));
                // 如果它代表着当前最接近的匹配则选择作为构造函数
                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) {
                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 {
                beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
                        mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
            }
    
            // 将构造的实例加入BeanWrapper
            bw.setWrappedInstance(beanInstance);
            return bw;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
        }
    }
    

    3. 无参构造器实例化,instantiateBean方法

    // 使用其默认构造函数实例化给定的bean
    protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
        try {
            Object beanInstance;
            final BeanFactory parent = this;
            // 获取系统的安全管理接口,JDK标准的安全管理API
            if (System.getSecurityManager() != null) {
                // 这里是一个匿名内置类,根据实例化策略创建实例对象
                beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    @Override
                    public Object run() {
                        return getInstantiationStrategy().instantiate(mbd, beanName, parent);
                    }
                }, getAccessControlContext());
            }
            else {
                // 将实例化的对象封装起来  
                beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
            }
            BeanWrapper bw = new BeanWrapperImpl(beanInstance);
            initBeanWrapper(bw);
            return bw;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
        }
    }
    
    @Override
    public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
        // 如果Bean定义中没有方法覆盖,则就不需要CGLIB父类类的方法
        if (beanDefinition.getMethodOverrides().isEmpty()) {
            Constructor<?> constructorToUse;
            synchronized (beanDefinition.constructorArgumentLock) {
                // 获取对象的构造方法或工厂方法
                constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
                // 如果没有构造方法且没有工厂方法
                if (constructorToUse == null) {
                    // 使用JDK的反射机制,判断要实例化的Bean是否是接口
                    final Class<?> clazz = beanDefinition.getBeanClass();
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }
                    try {
                        if (System.getSecurityManager() != null) {
                            // 这里是一个匿名内置类,使用反射机制获取Bean的构造方法
                            constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
                                @Override
                                public Constructor<?> run() throws Exception {
                                    return clazz.getDeclaredConstructor((Class[]) null);
                                }
                            });
                        }
                        else {
                            constructorToUse =  clazz.getDeclaredConstructor((Class[]) null);
                        }
                        beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
                    }
                    catch (Exception ex) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                    }
                }
            }
            // 使用BeanUtils实例化
            return BeanUtils.instantiateClass(constructorToUse);
        }
        else {
            // 否则使用CGLIB来实例化对象  
            return instantiateWithMethodInjection(beanDefinition, beanName, owner);
        }
    }
    

    相关文章

      网友评论

          本文标题:Spring4 Bean实例化源码

          本文链接:https://www.haomeiwen.com/subject/dknimqtx.html