当前位置:首页 > 服务端 > 5.7创建bean

5.7创建bean

当经历过resolveBeforeInstantiation方法后,程序有两个选择。 如果创建了代理或者说重写了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法并在方法postProcessBeforeinstantiation中改变了bean,则直接返回就可以了。否则需要进行常规bean的创建。而这常规bean的创建就在doCreateBean中完成。
AbstractAutowireCapableBeanFactory
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {

    if (logger.isTraceEnabled()) {
        logger.trace("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,根据设定的class属性或者根据className来解析Class
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    //验证及准备覆盖方法
    try {
        mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                                               beanName, "Validation of method overrides failed", ex);
    }

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        //给BeanPostProcessors一个机会来返回一个代理用来来替代真正的实例(AOP?)
        //如果自己实现了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法
        //并在postProcessBeforeInstantiation中改变了bean,则直接返回。
        //否则需要进行常规bean创建(doCreateBean)
        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 {
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("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);
    }
}
AbstractAutowireCapableBeanFactory
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        //根据指定bean使用对应的策略创建新的实例,如工厂方法、构造函数自动注入、简单初始化
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    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 {
                //应用MergedBeanDefinitionPostProcessor
                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.
    //是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                         "' to allow for resolving potential circular references");
        }
        //为避免后期循环依赖,可以在bean初始化完成前将创建的beanFactory加入工厂
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        //对bean进行填空,将各个属性值注入,其中,可能存在依赖于其他bean的属性。
        //则会递归初始值依赖bean
        populateBean(beanName, mbd, instanceWrapper);
        //调用初始化方法,比如init-method
        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);
        //earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
        if (earlySingletonReference != null) {
            //如果exposedObject没有初始化方法中被改变,也就是没有被增强
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    //检测依赖
                    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                        actualDependentBeans.add(dependentBean);
                    }
                }
                /*
                     * 因为bean创建后其所依赖的bean一定是已经创建的,
                     * actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有全部创建完
                     * 也就是说存在循环依赖
                     */
                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 " +
                                                               "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }

    // Register bean as disposable.
    try {
        //根据scope注册bean
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}
 
CreateBean函数的概要思路:
1.如果是单例则需要首先清楚缓存。
2.实例化bean,将BeanDefinition转换为BeanWrapper。
  • 如果存在工厂方法则使用工厂方法进行初始化。
  • 一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并初始化。
  • 如果既不存在工厂方法,也不存在带有参数的构造函数,则使用默认的构造器进行bean实例化。
3.MergedBeanDefinitionPostProcessor的应用。(Bean合并后的处理,Autowired注解正是通过此方法实现诸如类型的预解析)
4.依赖处理。

Spring 会有循环依赖的情况,例如,当 A 中含有 B 的属性,而 B 中又含有 A 的属性时就会构成个循环依赖,此时如果 A B 都是单例,那么在 Spring 中的处理方式就是当创 B 时候,涉及自动注入 A 的步骤时,并不是直接去再次A,而是通过放入缓存中的 ObjectFactory 来创建实例,这样就解决了循环依赖的问题

5.属性填充。将所有属性填充到bean的实例中。
6.循环依赖检查。
Spring中解决循环依赖只对单例有效。而对于prototype的bean,Spring没有好的解决方法,唯一要做的就是抛出异常。
7.注册disposableBean。
如果配置了destory-method,这里需要注册以便于在销毁时候调用。
8.完成创建并返回。
 
5.7.1创建bean的实例
AbstractAutowireCapableBeanFactory
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    //解析class
    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());
    }

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    //如果工厂方法不为空则使用工厂方法初始化策略
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    //判断使用那个构造函数进行实例化是比较消耗性能的步骤
    //如果已经解析过则不需要重复解析而是直接从RootBeanDefinition中的属性
    //resoIvedConstructorOrFactoryMethod缓存的值去取,否则需要再次解析,
    //并将解析的结果添加至 RootBeanDefinition 中的属性resolvedConstructorOrFactoryMethod中
    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);
        }
    }

    // Candidate constructors for autowiring?
    //需要根据参数解析构造函数
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        //构造函数自动注入
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    //首选构造器是否是默认构造器
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    //使用默认构造器构造
    return instantiateBean(beanName, mbd);
}

 

createBeanInstance方法实例化的逻辑:
1.如果在RootBeanDefinition中存在factoryMethodName属性,或者说在配置文件中配置了factory-method,那么Spring会尝试使用instantiateUsingFactoryMethod(bean-Name,mbd,args)方法根据RootBeanDefinition中的配置生成bean的实例。
2.解析构造函数并进行构造函数的实例化。因为一个bean对应的类中可能会有多个构造器,而每一个构造函数的参数不同,Spring在根据参数及类型判断最终会使用那个构造器进行实例化。但是这个判断过程是比较消耗性能的步骤,所以采用缓存机制,如果已经解析过这不需要重复解析而是直接从RootBeanDefinition中的属性resolvedConstruc-torOrFactoryMethod缓存的值去取,否则需要再次解析,并将解析的结果添加到RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod中。
ok,我们看看第2步解析构造函数并进行构造函数的实例化。
一:autowireConstructor(构造函数自动注入)
AbstractAutowireCapableBeanFactory
protected BeanWrapper autowireConstructor(
    String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

    return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
ConstructorResolver
/**
* 通过构造函数实例化需要确定三个属性:构造的参数、构造函数(通过构造参数判断)、参数类型。
* 这一段的逻辑就是找到这三个属性,然后交给instantiate函数实例化
*/
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
    @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

    BeanWrapperImpl bw = new BeanWrapperImpl();
    this.beanFactory.initBeanWrapper(bw);

    Constructor<?> constructorToUse = null;
    ArgumentsHolder argsHolderToUse = null;
    Object[] argsToUse = null;

    //expliciArgs是通过getBean方法传入
    //如果getBean方法调用的时候指定方法参数那么直接使用
    if (explicitArgs != null) {
        argsToUse = explicitArgs;
    }
    else {
        //如果在getBean方法的时候没有指定则尝试从配置文件中解析
        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) {
            //解析参数类型,如给定方法的构造函数A(int,int)则通过此方法后就会把配置中的("1","1")转换为(1,1)
            //缓存中的值可能是原始值也可能是最终值
            argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
        }
    }

    //没有被缓存
    if (constructorToUse == null || argsToUse == null) {
        // 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);
            }
        }

        //如果构造器或者方法的数量只有一个,并且getBean时没有传入参数,
        //而且构造函数注入属性(对应bean属性constructor-arg)为空
        //那么通过默认的无参构造器进行创建bean(判断条件是该唯一方法无参数那么就是默认无参构造)
        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.
        //mbd.getResolvedAutowireMode()自动注入模式,对应bean属性autowire。默认不
        boolean autowiring = (chosenCtors != null ||
                              mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
        ConstructorArgumentValues resolvedValues = null;

        int minNrOfArgs;
        //两种方式获取参数
        //方式一:获取getBean传入的参数
        if (explicitArgs != null) {
            minNrOfArgs = explicitArgs.length;
        }
        else {
            //方式二:获取bean标签中construct-arg标签传入的参数
            //提取配置文件中的配置的构造函数参数
            ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
            //用于承载解析后的构造函数参数的值
            resolvedValues = new ConstructorArgumentValues();
            //能解析到的参数个数
            minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
        }

        //排序给定的构造函数,public构造函数优先参数数量降序,非public构造函数参数数量降序
        AutowireUtils.sortConstructors(candidates);
        int minTypeDiffWeight = Integer.MAX_VALUE;
        Set<Constructor<?>> ambiguousConstructors = null;
        Deque<UnsatisfiedDependencyException> causes = null;

        //通过构造函数的参数个数与方式一、方式二中的参数比较确定选用那个构造函数
        for (Constructor<?> candidate : candidates) {
            int parameterCount = candidate.getParameterCount();

            if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
                // Already found greedy constructor that can be satisfied ->
                // do not look any further, there are only less greedy constructors left.
                //如果已经找到选用的构造函数或者需要的参数小于当前构造函数参数个数则终止
                //因为已经按照参数个数降序排列
                break;
            }
            if (parameterCount < minNrOfArgs) {
                //参数个数不相等
                continue;
            }

            ArgumentsHolder argsHolder;
            Class<?>[] paramTypes = candidate.getParameterTypes();
            //方式二:通过bean标签中construct-arg标签传入的参数初始化
            if (resolvedValues != null) {
                //有参数则根据值构造对应参数类型的参数
                try {
                    //@ConstructorProperties注解的用法
                    //在Spirng中通过构造方法注入时,Spring提供了一种新的方法可以让你手动指定参数中对应的beanName
                    //然后根据beanName去获取bean,相当于去容器中getBean一样,性能快。
                    String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
                    if (paramNames == null) {
                        //pnd 方法参数名称的解析器策略
                        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 ArrayDeque<>(1);
                    }
                    causes.add(ex);
                    continue;
                }
            }
            else {
                // Explicit arguments given -> arguments length must match exactly.
                //方式一:通过getBean传入的参数初始化
                if (parameterCount != 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);
        }

        //如果不是通过getBean方式传值并且参数持有者不为空,那么将解析的构造函数加入缓存中
        if (explicitArgs == null && argsHolderToUse != null) {
            argsHolderToUse.storeCache(mbd, constructorToUse);
        }
    }

    Assert.state(argsToUse != null, "Unresolved constructor arguments");
    //将构建的实例加入BeanWrapper中
    bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
    return bw;
}
很长的函数,大致逻辑:
通过构造函数实例化需要确定三个属性:构造的参数、构造函数(通过构造参数判断)、参数类型。这一段的逻辑就是找到这三个属性,然后交给instantiate函数实例化。参数会从缓存中获取、传入的参数explicitArgs、配置文件三种方式获取。构造函数会从指定的(传入的)构造函数获取、缓存中获取,如果都没有,将获取所有的或者部分的函数(根据mbd.isNonPublicAccessAllowed()判断),对比函数与参数得到构造函数。
1.构造函数参数的确定
  • 缓存中获取    
确定参数的方法如果之前已经分析过,也就是说构造函数参数已经记录在缓存中,那么便可以直接拿来使用。需要注意的是,缓存中缓存的可能是参数的最终类型也可能是参数的初始类型,例如构造参数中要求的是int类型,但是原始的参数值可能是String类型,那么即使在缓存中拿到参数,也需要经过类型转换器的过滤确保类型对应。
 
  • 根据explicitArgs参数判断
如果传入的参数explicitArgs不为空,那么可以直接确定参数,因为explicitArgs参数是在调用Bean的时候用户指定的,在BeanFactory类中存在这样的方法。
Object getBean(String name, Object... args) throws BeansException;
在获取bean的时候,用户不但可以指定bean的名称还可以指定bean所对应类的构造函数或者工厂方法的方法参数,主要用于静态工厂方法的调用,而这里是需要给定完全匹配的参数的,所以explicitArgs不为空,便可以用它确定构造函数。
 
  • 配置文件获取
如果不能根据传入的参数explicitArgs确定构造函数的参数也无法在缓存中得到相关的信息,那么只能开始新一轮的分析。
分析从获取配置文件中的配置的构造函数信息开始,经过之前的分析,我们知道,Spring中配置文件中的信息经过转换都会通过BeanDefinition实例承载,也就是参数mbd,那么可以通过调用mbd.getContrsuctorArgumentValues()来提取配置文件中的配置的构造函数参数。然后交给resolveConstructorArguments方法处理参数,并返回能个数。
 
2.构造函数确定
    经过第一步后已经确定了构造函数的参数,解析来的任务是根据构造函数参数在所有构造函数中锁定对应的构造函数,而匹配的方法就是根据参数个数匹配,所以在匹配之前需要先对构造函数按照public构造函数优先参数数量降序,非public构造函数参数数量降序。这样可以在遍历的情况下迅速判断排在后面的构造函数参数个数是否符合条件。
    由于在配置文件中除了使用参数位置索引的方式创建,同时还支持指定参数名称进行设定参数值的情况。比如<constructor-arg name="aaa">,那么这种情况下就需要首先确定构造函数中的参数名称。
    获取参数名称可以有两种方式,一种是通过注解的方式直接获取,另一种就是使用Spring中提供的工具类ParameterNameDiscoverer来获取。
    构造函数、参数名称、参数类型、参数值都拿到后就可以锁定构造函数以及转换对应的参数类型。
 
3.根据确定的构造函数转换对应的参数类型
使用Spring中提供的类型转换器或者用户提供的自定义类型转换器进行转换。
 
4.构造函数不确定性的验证
有时候即使构造函数、参数名称、参数类型、参数值都确定后也不一定会直接锁定构造函数,不同构造函数的参数为父子关系,所以Spring在最后又做了一次验证。
 
5.instantiateBean根据实例化策略以及得到的构造函数、构造函数参数实例化Bean。
 
二、instantiateBean(使用默认构造器构造)
AbstractAutowireCapableBeanFactory
/**
* Instantiate the given bean using its default constructor.
*/
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged(
                (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
                getAccessControlContext());
        }
        else {
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
        }
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        initBeanWrapper(bw);
        return bw;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}
Spring把精力都放在了构造函数以及参数的匹配上,所以如果没有参数的话那将是非常简单的一件事。直接调用实例化策略进行实例化。
 
三、实例化策略
SimpleInstantiationStrategy
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // Don't override the class with CGLIB if no overrides.
    //如果有需要覆盖或者动态替换的方法则当然需要使用cglib进行动态代理,
    //因为可以在创建代理的同时将动态方法织入类中
    //但是如果没有需要动态改变的方法,为了方便直接反射就可以了
    if (!bd.hasMethodOverrides()) {
        Constructor<?> constructorToUse;
        synchronized (bd.constructorArgumentLock) {
            constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse == null) {
                final Class<?> clazz = bd.getBeanClass();
                if (clazz.isInterface()) {
                    throw new BeanInstantiationException(clazz, "Specified class is an interface");
                }
                try {
                    if (System.getSecurityManager() != null) {
                        constructorToUse = AccessController.doPrivileged(
                            (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                    }
                    else {
                        constructorToUse = clazz.getDeclaredConstructor();
                    }
                    //缓存,在ConstructorResolver的autowireConstructor方法有用到
                    bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                }
                catch (Throwable ex) {
                    throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                }
            }
        }
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        // Must generate CGLIB subclass.
        return instantiateWithMethodInjection(bd, beanName, owner);
    }
}

CglibSubclassingInstantiationStrategy
public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
            Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
            Object instance;
            if (ctor == null) {
                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;
        }
程序中,首先判断如果beanDefinition.getMethodOverrides()为空也就是用户没有使用replace或者lookup的配置方法,那么直接使用反射的方式,简单便捷,但是如果使用了这两个特性,在直接使用反射的方式创建实例就不妥了,因为需要将这两个配置提供的功能切入进去,所以就必须使用动态代理的方式将包含两个特性所对应的逻辑的拦截器设置进去,这样才可以保证在调用方法的时候会被相应的拦截器增强,返回值为包含拦截器的代理实例。
 
5.7.2记录创建bean的ObjectFactory(解决循环依赖的缓存中的数据就是在这里缓存的
在doCreateBean函数中有这样一段代码
AbstractAutowireCapableBeanFactory
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
        
    //......

    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    //是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                         "' to allow for resolving potential circular references");
        }
        //为避免后期循环依赖,可以在bean初始化完成前将创建的beanFactory加入工厂
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    
    //......
}

AbstractAutowireCapableBeanFactory
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;
    //对bean再一次依赖引用,主要应用SmartInstantiationAwareBeanPostProcessor
    //其中我们熟悉的AOP就是在这里将advice动态织入bean中,若没有直接返回,不做任何处理
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
            exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);
        }
    }
    return exposedObject;
}

DefaultSingletonBeanRegistry
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        synchronized (this.singletonObjects) {
            if (!this.singletonObjects.containsKey(beanName)) {
                this.singletonFactories.put(beanName, singletonFactory);
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);
            }
        }
    }
解决循环依赖的缓存中的数据就是在这里缓存的。
earlySingletonExposure:从字面意思理解就是提早曝光的单例。mbd.isSingleton()、this.allowCircularReferences、isSingletonCurrentInCreation(beanName)这三个决定了这个参数。
mbd.isSingleton():此RootBeanDefinition是否是单例。
this.allowCircularReferences:是否允许循环依赖,很抱歉,并没有找到在配置文件中如何配置,但是在AbstractRefreshableApplicationContext中提供了设置函数,可以通过硬编码的方式进行设置或者可以通过自定义命名空间进行配置。其中硬编码的方式代码如下:
ClassPathXmlApplicationContext contex =
    new ClassPathXmlApplicationContext("/circularReference.xml");
contex.setAllowCircularReferences(false);
isSingletonCurrentInCreation(beanName):该bean是否正在创建中,在Spring中有个专门的属性默认为DefaultSingletonBeanRegistry的singletonsCurrentlyInCreation来记录bean的记载状态,在bean开始创建前会将beanName记录在属性中,在bean创建结束后会将beanName从属性中移除。以scope为singleton的为例,在singleton下记录属性的函数是在DefaultSingletonBeanRegistry类的beforeSingletonCreation(beanName)和afterSingletonCreation(beanName)中,在这两段函数中分别this.singletonsCurrently-InCreate.add(beanName)与this.singletonsCurrentlyInCreate.remove(beanName)来进行状态的记录与移除。
满足三个条件后会执行addSingletonFactory操作。记录缓存。记录下来的缓存会在下图中的getBean(A)中调用。比如AbstractBeanFactory的doGetBean函数的getSingleton(String beanName, ObjectFactory<?> singletonFactory)。
5.7创建bean _ JavaClub全栈架构师技术笔记
 
5.7.3属性注入
AbstractAutowireCapableBeanFactory
/**
     * Populate the bean instance in the given BeanWrapper with the property values
     * from the bean definition.
     */
@SuppressWarnings("deprecation")  // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        }
        else {
            // Skip property population phase for null instance.
            //没有可以填充的属性
            return;
        }
    }

    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    //给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前来改变bean
    //如:可以用来支持属性注入的类型
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            //返回值为是否继续填充bean
            if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                return;
            }
        }
    }

    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // Add property values based on autowire by name if applicable.
        //根据名称自动注入
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // Add property values based on autowire by type if applicable.
        //根据类型自动注入
        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }

    //后处理器已经初始化
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    //需要依赖检查
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            if (pvsToUse == null) {
                if (filteredPds == null) {
                    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                }
                //对所有需要依赖检查的属性进行-后处理
                pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    return;
                }
            }
            pvs = pvsToUse;
        }
    }
    if (needsDepCheck) {
        if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        //依赖检查,对应depends-on属性,3.0后已经弃用属性
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    if (pvs != null) {
        //将属性应用到bean中
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}
populateBean函数提供的处理流程:
1.InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation函数的应用。此函数可以控制程序是否继续进行属性填充。
2.根据注入类型(byName / byType),提取依赖的bean,并统一存入Property Value中。
3.应用 InstantiationAwareBeanPostProcessor处理器的postProcessProperty Values方法,对属性获取完毕填充前对属性的再次处理。典型应用是RequiredAnnotationBean-PostProcessor类中对属性的验证。
4.将所有Property Values中的属性填充到BeanWrapper中。
 
autowireByName函数
AbstractAutowireCapableBeanFactory
protected void autowireByName(
    String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

    //寻找bw中需要依赖注入的属性
    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    for (String propertyName : propertyNames) {
        if (containsBean(propertyName)) {
            //递归初始化相关的bean
            Object bean = getBean(propertyName);
            pvs.add(propertyName, bean);
            //注册依赖
            registerDependentBean(propertyName, beanName);
            if (logger.isTraceEnabled()) {
                logger.trace("Added autowiring by name from bean name '" + beanName +
                             "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
            }
        }
        else {
            if (logger.isTraceEnabled()) {
                logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
                             "' by name: no matching bean found");
            }
        }
    }
}
autowireByType函数
AbstractAutowireCapableBeanFactory
protected void autowireByType(
    String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

    //获取自定义的类型转换器
    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }

    Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
    //寻找bw中需要依赖注入的属性
    String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
    for (String propertyName : propertyNames) {
        try {
            PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
            // Don't try autowiring by type for type Object: never makes sense,
            // even if it technically is a unsatisfied, non-simple property.
            if (Object.class != pd.getPropertyType()) {
                //探测指定属性的set方法
                MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
                // Do not allow eager init for type matching in case of a prioritized post-processor.
                boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
                DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
                //解析指定beanName的属性所匹配的值,并把解析到的属性名称存储在autowiredBeanNames中
                //当属性存在多个封装bean时。
                //如 @Autowire private List<A> aList;将会找到所有匹配A类型的Bean并将其注入
                Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
                if (autowiredArgument != null) {
                    //添加到待注入的bean列表中
                    pvs.add(propertyName, autowiredArgument);
                }
                for (String autowiredBeanName : autowiredBeanNames) {
                    //注册依赖
                    registerDependentBean(autowiredBeanName, beanName);
                    if (logger.isTraceEnabled()) {
                        logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
                                     propertyName + "' to bean named '" + autowiredBeanName + "'");
                    }
                }
                autowiredBeanNames.clear();
            }
        }
        catch (BeansException ex) {
            throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
        }
    }
}
实现根据名称自动匹配的第一步就是寻找bw中需要依赖注入的属性。同样对于根据类型自动匹配的实现来讲第一步也是寻找bw中需要依赖注入的属性,然后遍历这些属性并寻找类型匹配的bean,其中最复杂的就是寻找类型匹配的bean。同时,Spring提供了对集合类型注入的支持。如使用注解的方式:
@Autowired
private List<A> aList;
对于寻找类型类型匹配的逻辑实现封装在了DefaultListableBeanFactory.resolveDependency函数中。
 
applyPropertyValues
程序运行到这里,已经完成了对所有注入属性的获取,但是获取的属性是以PropertyValues形式存在的。还并没有应用到已经实例化的bean中,这一工作是在applyPropertyValues中。
AbstractAutowireCapableBeanFactory
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
    if (pvs.isEmpty()) {
        return;
    }

    if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
        ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
    }

    MutablePropertyValues mpvs = null;
    List<PropertyValue> original;

    if (pvs instanceof MutablePropertyValues) {
        mpvs = (MutablePropertyValues) pvs;
        //如果mpvs中的值已经被转换为对应的类型那么可以直接设置到beanwapper中
        if (mpvs.isConverted()) {
            // Shortcut: use the pre-converted values as-is.
            try {
                bw.setPropertyValues(mpvs);
                return;
            }
            catch (BeansException ex) {
                throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
            }
        }
        original = mpvs.getPropertyValueList();
    }
    else {
        //如果pvs并不是使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法
        original = Arrays.asList(pvs.getPropertyValues());
    }

    TypeConverter converter = getCustomTypeConverter();
    if (converter == null) {
        converter = bw;
    }
    //获取对应的解析器
    BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

    // Create a deep copy, resolving any references for values.
    List<PropertyValue> deepCopy = new ArrayList<>(original.size());
    boolean resolveNecessary = false;
    //遍历属性,将属性转换为对应类的对应属性的类型
    for (PropertyValue pv : original) {
        if (pv.isConverted()) {
            deepCopy.add(pv);
        }
        else {
            String propertyName = pv.getName();
            Object originalValue = pv.getValue();
            if (originalValue == AutowiredPropertyMarker.INSTANCE) {
                Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
                if (writeMethod == null) {
                    throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
                }
                originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
            }
            Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
            Object convertedValue = resolvedValue;
            boolean convertible = bw.isWritableProperty(propertyName) &&
                !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
            if (convertible) {
                convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
            }
            // Possibly store converted value in merged bean definition,
            // in order to avoid re-conversion for every created bean instance.
            if (resolvedValue == originalValue) {
                if (convertible) {
                    pv.setConvertedValue(convertedValue);
                }
                deepCopy.add(pv);
            }
            else if (convertible && originalValue instanceof TypedStringValue &&
                     !((TypedStringValue) originalValue).isDynamic() &&
                     !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                pv.setConvertedValue(convertedValue);
                deepCopy.add(pv);
            }
            else {
                resolveNecessary = true;
                deepCopy.add(new PropertyValue(pv, convertedValue));
            }
        }
    }
    if (mpvs != null && !resolveNecessary) {
        mpvs.setConverted();
    }

    // Set our (possibly massaged) deep copy.
    try {
        bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    }
    catch (BeansException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    }
}
1.如果PropertyValues已经被转换为对应的类型那么可以直接设置到beanWrapper中。
2.如果PropertyValues没有转换为对应的类型,那么转换,并且将 converted 属性设置为true(convertend为是否已转换)。
 
5.7.4初始化bean(此函数的目的是进行客户设定的初始化方法调用,Aware和init-mehtod、InitializtingBean
bean配置时bean中有一个init-method的属性,这个属性的作用是在bean实例化前调用init-method指定的方法来根据用户业务进行相应的实例化。在执行此方法前,Spring已经执行过bean的实例化,并且进行了属性填充,而就在这时将会调用用户设定的初始化方法。 此函数的目的是进行客户设定的初始化方法调用,但是除此之外还有些其他必要的工作。
AbstractAutowireCapableBeanFactory
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        //对特殊的bean处理:Aware、BeanClassLoaderAware、BeanFactoryAware
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        //应用后处理器
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        //激活用户自定义的init方法
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        //后处理器应用
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}
1)激活Aware方法(bean可以通过实现Aware接口,获取到Spring容器的一些资源)
Aware的使用。Spring中提供了一些Aware接口,比如BeanFactoryAware、Applicatio-ContextAware、ResourceLoaderAware、ServletContextAware等。实现这些Aware接口的bean在被初始化之后,可以取得一些相对的资源。例如实现BeanFactoryAware的bean在初始化之后,Spring容器将会注入BeanFactory的实例。而实现Application-ContextAware的bean,在bean被初始化后,将会被注入ApplicationContext的实例。
Aware示例:
1.定义普通bean
public class Phone {

    public void cell(){
        System.out.println("もしもし");
}

}
2.定义BeanFactoryAware类型的bean
public class AwareImpl implements BeanFactoryAware {

    private BeanFactory beanFactory;

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
}

    public void testAware(){
        //通过phone这个bean从beanFactory获取实例
Phone phone = (Phone) beanFactory.getBean("phone");
phone.cell();
}

}
3.配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="phone" class="aware.Phone"></bean>

    <bean id="awareImpl" class="aware.AwareImpl"></bean>

</beans>
4.测试
public class TestAware {
    public static void main(String[] args) {
        ApplicationContext applicationContext = 
                new ClassPathXmlApplicationContext("aware.xml");
AwareImpl aware = 
                (AwareImpl) applicationContext.getBean("awareImpl");
aware.testAware();
}
}
源码中的实现方式,通过invokeAwareMethods函数调用了自己写的实现类AwareImpl。AwareImple中的BeanFactory其实是AbstractAuwowireCapableBean-Factory,通过它的getBean获取到对象。
AbstractAuwowireCapableBeanFactory
private void invokeAwareMethods(String beanName, Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

 

2)处理器的应用
BeanPostProcessor,这是Spring开放式架构中一个必不可少的亮点,给用户充足的权限去更改或者拓展Spring,而除了BeanPostProcessor外还有很多其他的PostProce-ssor,当然大部分都是以此为基础,继承自BeanPostProcessor。BeanPostProcessor的使用位置就是这里,在调用客户自定义初始化方法前以及调用自定义初始化方法后分别会调用postProcessBeforeInitialization和postProcessAfterInitialization方法。使用户可以根据自己的业务需求进行响应的处理。
AbstractAuwowireCapableBeanFactory
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}
3)激活自定义的init方法(bean通过实现InitializingBean接口实现自己的初始化逻辑)
自定义的初始方法除了使用配置init-method外,还可以使用自定义的bean实现InitializingBean接口,并在afterPropertiesSet中实现自己的初始化业务逻辑。
init-method与afterPropertiesSet都是在初始化时执行,执行顺序是afterPropertiesSet先执行,init-method后执行。
AbstractAutowireCapableBeanFactory
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
    throws Throwable {

    //首先会检查是否是InitializingBean,如果是的话需要调用afterPropertiesSet方法
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (logger.isTraceEnabled()) {
            logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
        }
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                    ((InitializingBean) bean).afterPropertiesSet();
                    return null;
                }, getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            //属性初始化后的处理
            //InitializingBean接口
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
            //调用自定义初始化方法
            //配置的init-mehtod
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}
 
5.7.5注册DisposableBean
Spring中不但提供了对于初始化方法的拓展入口,同样也提供了销毁方法的拓展入口,对于销毁方法的拓展,除了我们熟知的配置属性destroy-method方法外,用户还可以注册后处理器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法。
AbstractbeanFactory
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
        if (mbd.isSingleton()) {
            // Register a DisposableBean implementation that performs all destruction
            // work for the given bean: DestructionAwareBeanPostProcessors,
            // DisposableBean interface, custom destroy method.
            //单例模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean
            //并且对所有bean使用DestructionAwareBeanProcessor处理
            //DisposableBean destructionAwareBeanProcessors
            registerDisposableBean(beanName, new DisposableBeanAdapter(
                bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
        }
        else {
            // A bean with a custom scope...
            //自定义scope的处理
            Scope scope = this.scopes.get(mbd.getScope());
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
            }
            scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(
                bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));
        }
    }
}

 





作者:_Shing
来源链接:https://www.cnblogs.com/-shing/p/cfa48bef3629116822f16bd0530d8f42.html

版权声明:
1、Java侠(https://www.javaxia.com)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaxia.com/server/125331.html

分享给朋友:

“5.7创建bean” 的相关文章

软件工程复习要点2022年05月17日 14:38:01
[C++]VC自定义发IP包例子2022年05月17日 20:41:27
MySQL安装之yum安装2022年05月19日 19:54:29
Java日志框架那些事儿2022年05月19日 20:04:37
多线程编程(1)2022年05月20日 21:26:51
Dart微基准测试第一部分2022年05月23日 20:48:42
信息系统项目管理案例22022年05月24日 22:36:24
概率论快速学习02:概率公理2022年05月26日 21:02:52