美文网首页
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实例化源码

    介绍 Spring4的依赖注入的过程是先Bean实例化,然后进行属性的填充。而其中Bean的实例化的过程,可能会工...

  • springboot Bean创建

    供参考文献 Spring bean 创建过程源码解析 图解Bean实例化 来自【Spring】Spring bea...

  • bean生命周期以及作用域

    bean生命周期: 简单点说就是:bean的实例化–>bean的初始化–>bean的使用–>bean的销毁 实例化...

  • spring 5.0.x源码学习系列九: FactoryBean

    前言 上篇博客spring 5.0.x源码学习系列八: 实例化bean之使用构造方法创建bean、自动装配与循环依...

  • spring bean管理

    1.bean实例化的方式 (1)bean的实例化就是通过配置文件创建对象(2)bean实例化三种创建方式第一种:通...

  • Spring学习笔记

    Spring实例化bean1、构造方法实例化bean 2、使用静态工厂实例化 类中的静态方法如下: 3、使用动态工...

  • Spring容器与获取Bean的方法

    在Spring IOC容器读取 Bean 配置、创建 Bean 实例之前必须对它进行实例化,只有进行实例化后才能从...

  • IOC-Bean

    Spring 容器根据实例化策略对 Bean 进行实例化。 实例化完成后,如果该 bean 设置了一些属性的话,则...

  • SpringBean的生命周期

    实例化 实例化一个Bean,也就是我们常说的new。 IOC依赖注入 按照Spring上下文对实例化的Bean进行...

  • 24--Spring解决bean之间的循环依赖

    通过前几节的分析,已经成功将bean实例化,但是大家一定要将bean的实例化和完成bean的创建区分开,bean的...

网友评论

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

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