spring源码解析九(创建未填充属性的bean实例)

上一节,分析了下,bean的创建,但是没有具体分析一些重要的方法,而是简单的从整体看了下bean实例的创建,大概就是从缓存中获取,
未命中,创建bean实例,解决循环依赖,填充bean属性,到最后的收尾工作
今天这节内容,我们分析第一个比较重要的方法,createBeanInstance,我把他比喻为我们买的毛坯房,还没有装修,只是房子已经盖起来了
那马这个方法做的事情,就是盖房子的事情,废话不多说了,我们直接进入今天的主题

#createBeanInstance
#AbstractAutowireCapableBeanFactory
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        //这个方法会通过先检查bean中是否有bean的全路径名称,有的话,直接返回,如果没有,就通过反射的方式获取bean类
        //这个方法,后期有时间咱们可以再看,今天就不解析这个方法了
        Class beanClass = resolveBeanClass(mbd, beanName);

        //这里的判断条件是说,如果beanClass不为null的情况下
        //1:不是被publc修饰.并且不允许公共访问的话,直接抛出异常
        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容器中查询是否存在这个bean实例,存在的话,调用obtainFromSupplier创建bean对象
        Supplier instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }

        //判断bean定义中是否存在工厂方法,存在的话,使用instantiateUsingFactoryMethod创建bean对象
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // 这里是说如果是重复实例化一个bean,resolved会被修改为true,不用在判断使用哪个方式创建bean对象
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        //如果resolved被修改为true,则进入到下面这段逻辑
        if (resolved) {
            if (autowireNecessary) {
                //通过构造方法自动注入的方式创建bean对象
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                //通过通用的方式创建bean对象
                return instantiateBean(beanName, mbd);
            }
        }

        //通过后置处理器获取构造器数组,
        //1;判断构造器数组是否为空
        //2:bean定义中自动注入模式是否被指定为构造器注入
        //3:是否存在构造器参数
        //4:参数是否为空,
        //只要某一项为true,就会使用构造方法自动注入的方式创建对象
        Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        //如果以上都不成立,看看是否指定了bean定义的首选构造函数,指定的话
        ctors = mbd.getPreferredConstructors();
        if (ctors != null) {
            //通过构造方法自动注入的方式创建对象
            return autowireConstructor(beanName, mbd, ctors, null);
        }

        // 通过通用方式创建bean对象
        return instantiateBean(beanName, mbd);
    }

简单总结下,以上说到了spring通过几种方式创建bean对象
1:判断当前解析的bean是否在Supplier容器中存在,如果存在,通过obtainFromSupplier的方式创建bean对象
2:判断bean定义是否存在工厂方法,存在的话,使用instantiateUsingFactoryMethod工厂方法的方式创建bean对象
3:对于相同的bean,就不会再去判断使用哪种方式创建了,直接使用构造方法自动注入的方式或者通用方法的方式创建对象
4:查看是否配置了指定的默认首选构造方式,指定的话,通过构造方法自动注入的方式创建对象
5:如果以上都不满足,直接通过通用的方式创建bean对象

我们先从通用的方式创建bean对象这个方法开始具体分析instantiateBean

#instantiateBean
#AbstractAutowireCapableBeanFactory
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
            Object beanInstance;
            final BeanFactory parent = this;
            //1:通过策略模式实例化bean对象
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
            //2:创建bean包装对象
            BeanWrapper bw = new BeanWrapperImpl(beanInstance);
            //3:初始化bean包装对象
            initBeanWrapper(bw);
            //返回bean包装对象
            return bw;
    }

#SimpleInstantiationStrategy
#instantiate
#为了看得清楚,我删除了,安全代码,以及异常信息代码,
    public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {

        //查看该bean是否被覆盖,因为默认我们的bean都是单例的,但是我们可以指定为原型模式,
        //也就是说如果当前bean如果配置了Scope注解,并将值设定为原型,或者在配置文件中指定了该bean为lookup-Method则会走else逻辑
        //通过cglib的方式创建bean对象,否则走if逻辑
        if (!bd.hasMethodOverrides()) {
            Constructor constructorToUse;
            synchronized (bd.constructorArgumentLock) {
                constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod;
                if (constructorToUse == null) {
                    final Class clazz = bd.getBeanClass();
                    //如果当前的clazz是接口,直接抛出异常
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }
                        //返回类指定的构造函数
                        constructorToUse = clazz.getDeclaredConstructor();

                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;

                }
            }
            //通过beanUtils实例化bean对象
            return BeanUtils.instantiateClass(constructorToUse);
        }
        else {
            //通过CGLIB创建bean对象
            return instantiateWithMethodInjection(bd, beanName, owner);
        }
    }

#BeanUtils
#BeanUtils.instantiateClass
public static  T instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException {
        Assert.notNull(ctor, "Constructor must not be null");
            //执行权限的设置
            ReflectionUtils.makeAccessible(ctor);
            //下面是一个三元运算符,
            //由于spring增加了对Kotlin的支持,所以这里会有通过Kotlin实例化一个bean对象的处理方式这个我们就不介绍了
            //有兴趣的同学可以研究下Kotlin我们主要看ctor.newInstance
            //我们终于看到了newInstance,这代表着我们已经生成一个对象了,也就是说通过一系列的操作通过bean的全限定类名最终
            //调用newInstance生成了实例
            ctor.newInstance(args);
            return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
                    KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));

    }

简单总结一下,
默认构造方式:
1:判断当前bean是否设置了lookup-method,如果设置了,就走cglib代理的方式创建bean,否则通过默认的方式创建bean
2:通过BeanUtils.instantiateClass最终调用newInstance的方式返回bean实例,
3:创建bean包装对象
4:初始化bean包装对象
5:返回bean包装对象

我们在简单介绍下通过CGLIB创建bean对象,我上面已经提到过,如果配置了lookup-methd,则会走else分支就是下面这个方法
instantiateWithMethodInjection(bd, beanName, owner);

在BeanFactories中使用的默认对象实例化策略。如果方法需要被容器重写以实现,则使用CGLIB动态生成子类

#CglibSubclassingInstantiationStrategy
@Override
    protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
        return instantiateWithMethodInjection(bd, beanName, owner, null);
    }

@Override
    protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
            @Nullable Constructor ctor, Object... args) {

        // Must generate CGLIB subclass...
        return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
    }


public Object instantiate(@Nullable Constructor ctor, Object... args) {
            //通过createEnhancedSubclass方法生成一个subclass(增强子类)
            Class subclass = createEnhancedSubclass(this.beanDefinition);
            //================================================================
            使用CGLIB为提供的bean 定义创建bean类的增强子类
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(beanDefinition.getBeanClass());
            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            if (this.owner instanceof ConfigurableBeanFactory) {
                ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
                enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
            }
            enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
            enhancer.setCallbackTypes(CALLBACK_TYPES);
            return enhancer.createClass();
            //==================================================================
            Object instance;
            if (ctor == null) {
                //这里有看见了熟悉的 BeanUtils.instantiateClass方法
                instance = BeanUtils.instantiateClass(subclass);
            }
            else {
                try {
                    Constructor enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
                    instance = enhancedSubclassConstructor.newInstance(args);
                }
                catch (Exception ex) {
                    throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
                            "Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
                }
            }
            // SPR-10785: set callbacks directly on the instance instead of in the
            // enhanced class (via the Enhancer) in order to avoid memory leaks.
            Factory factory = (Factory) instance;
            factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
                    new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
                    new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
            return instance;
        }

cglib我没有具体分析,就是给生成代理类,然后通过代理类调用 BeanUtils.instantiateClass的实例对象,就不做具体的分析了,大家可以看源码哈
以上就是我们通用的创建bean实例的方式

接下来,我们分析通过构造方法自动注入的方式创建bean

autowireConstructor(beanName, mbd, null, null);
#AbstractAutowireCapableBeanFactory


protected BeanWrapper autowireConstructor(
            String beanName, RootBeanDefinition mbd, @Nullable Constructor[] ctors, @Nullable Object[] explicitArgs) {
        //创建构造解析器对象
        return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
    }


#ConstructorResolver
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
            @Nullable Constructor[] chosenCtors, @Nullable Object[] explicitArgs) {

        //创建bean包装对象,并初始化
        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) {
                    //获取缓存的构造对象数组
                    argsToUse = mbd.resolvedConstructorArguments;
                    if (argsToUse == null) {
                        //如果缓存中不存在,就从部分准备好的数组对象中获取
                        argsToResolve = mbd.preparedConstructorArguments;
                    }
                }
            }
            if (argsToResolve != null) {
                //解析预处理参数
                argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
            }
        }

        //当构造器对象为null或者参数数组为null的时候进入下面的逻辑
        if (constructorToUse == null || argsToUse == null) {
            // 从指定的构造函数里获取构造对象
            Constructor[] candidates = chosenCtors;
            if (candidates == null) {
                //如果没有指定构造器,就从当前bean中的构造器
                Class beanClass = mbd.getBeanClass();
                    candidates = (mbd.isNonPublicAccessAllowed() ?
                            beanClass.getDeclaredConstructors() : beanClass.getConstructors());
            }

            //如果只配置了构造器对象,没有配置,参数,则会走这段逻辑,我们看源码也会最终看到BeanUtils.instantiateClass
            //就不做过多的解释了,这段代码比较简单,
            if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
                Constructor uniqueCandidate = candidates[0];
                if (uniqueCandidate.getParameterCount() == 0) {
                    synchronized (mbd.constructorArgumentLock) {
                        mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
                        mbd.constructorArgumentsResolved = true;
                        mbd.resolvedConstructorArguments = EMPTY_ARGS;
                    }
                    bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
                    return bw;
                }
            }

            // Need to resolve the constructor.
            boolean autowiring = (chosenCtors != null ||
                    mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.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);
            }

            //对构造器执行排序,因为可能我们在一个类中不止一个构造器,可能有多个构造器
            //如下所示,我定义了两个构造器
            //============================================
            public Dog(String names, int age, String sex) {
                    this.names = names;
                    this.age = age;
                    this.sex = sex;
                }

                public Dog(String names, int age) {
                    this.names = names;
                    this.age = age;
                }

                //配置文件:
                
                            
                            
                            
                        

                        
                            
                            
                 

                 运行后的结果是:
                 Dog{names='小黄', age=12, sex='雄性'}
                 Dog{names='小五', age=10, sex='null'}
            //==============================================
            //简单说一下排序.参数多的会排在前面,public修饰的会排在前面
            AutowireUtils.sortConstructors(candidates);
            int minTypeDiffWeight = Integer.MAX_VALUE;
            Set> ambiguousConstructors = null;
            LinkedList causes = null;

            for (Constructor candidate : candidates) {
                Class[] paramTypes = candidate.getParameterTypes();

                if (constructorToUse != null && argsToUse != 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;
                }


                //判断是否存在ConstructorProperties 注解,如果有注解,则是取注解的值执行赋值
                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,
                                getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
                    }
                    catch (UnsatisfiedDependencyException ex) {
                        if (logger.isTraceEnabled()) {
                            logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
                        }
                        // Swallow and try next constructor.
                        if (causes == null) {
                            causes = new LinkedList<>();
                        }
                        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<>();
                        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 != null) {
                argsHolderToUse.storeCache(mbd, constructorToUse);
            }
        }

        Assert.state(argsToUse != null, "Unresolved constructor arguments");
        bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
        return bw;
    }

以上就是创建bean实例的过程,下一节.我们来分析下,填充属性,既然bean实例创建完成了,就该装修了!

你可能感兴趣的:(spring源码解析九(创建未填充属性的bean实例))