关于java:Spring-Bean如何初始化的

31次阅读

共计 28540 个字符,预计需要花费 72 分钟才能阅读完成。

本文出处 Spring Bean 如何初始化的 转载请阐明出处

做 Java 都有很多年了,始终有一个纳闷:Spring 如何初始化 bean,怎么调用反射实例化对象的,本人入手来解除这个纳闷。
过来我认为 spring bean 对象实例化始终都是由 BeanPostProcessor 接口实现类去做的,我就是不晓得具体那个实现类,上面就去验证下这个猜测。

三级缓存

为什么面试官特地喜爱问创立 bean 的三级缓存,次要是因为 bean 创立都是随同着三级缓存之间的转换实现的,对象不同状态别离存在不同缓存中,上面我会在剖析代码时,顺便反对对象如何在缓存中流转的。
先理解下 spring 三级缓存。

    /** 一级缓存 用于寄存齐全能够应用单例 bean,也就是初始化实现并且注入所有依赖 */
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    /** 二级缓存 过早裸露单例对象,此时 bean 刚刚实现初始化,未实现属性注入和执行 init 办法 */
    private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

    /** 三级缓存  装载创立 bean 的工厂对象 */
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16)

三级缓存次要作用:创建对象 ObjectFactory 首先放入三级换缓存中,当调用 getObject 创立实例时,会将创立好对象退出二级缓存中,并且删除三级中缓存,当对象曾经实现初始化办法和属性注入,再将缓存增加到一级缓存中,并且删除二级缓存。

doGetBean

从源头开始找,所有 spring bean 初始化都是由 AbstractBeanFactory.doGetBean 办法实现的。上面我将源码减除臃肿局部,贴出来。

    protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
            throws BeansException {
        //name 前缀解决  beanFactory beanName 带有 & 结尾
        String beanName = transformedBeanName(name);
        Object beanInstance;
        // 从三级缓存去取 bean,三级中都没有则返回 null,阐明对象还没有创立
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) { // 如果缓存中 bean 是 FactoryBean 实例,要通过接口获取到理论 bean
            beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        }
        else { 
             // 判断 bean 对象标记是否正在创立中,如果正在创立中则不应该继续下去,呈现依赖循环就会呈现这个谬误
            if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);
            }
            BeanFactory parentBeanFactory = getParentBeanFactory();
            // 查看父容器是否存在,尝试从父容器中获取
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
                }
                else if (args != null) {return (T) parentBeanFactory.getBean(nameToLookup, args);
                }
                else if (requiredType != null) {return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
                else {return (T) parentBeanFactory.getBean(nameToLookup);
                }
            }

            if (!typeCheckOnly) { // 缓存中标记 beanName 正在被创立
                markBeanAsCreated(beanName);
            }
            StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
                    .tag("beanName", name);
            try {if (requiredType != null) {beanCreation.tag("beanType", requiredType::toString);
                }
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);
                // Guarantee initialization of beans that the current bean depends on.
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {  //bean 中 @DependsOn 信息,用于标记 bean 之间初始化程序,优先创立 @DependsOn   中 bean
                    for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between'" + beanName + "'and'" + dep + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'"+ beanName +"' depends on missing bean '"+ dep +"'", ex);
                        }
                    }
                }

                 // 创立单例对象
                if (mbd.isSingleton()) { // 重点就在这里实例化对象,getSingleton 就是在这里将创立实现对象退出到一级缓存中
                    sharedInstance = getSingleton(beanName, () -> {
                        try {return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) 
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    // 如果生成 bean 是 FactoryBean,再获取真正的对象
                    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                // 作用域 = prototype,因为不会放入缓存中,每次获取都要从新创立
                else if (mbd.isPrototype()) {
                    // It's a prototype -> create a new instance.
                    Object prototypeInstance = null;
                    try {beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {afterPrototypeCreation(beanName);
                    }
                    beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }

                else { // session request 这些作用域,由作用域容器去治理这些对象
                    String scopeName = mbd.getScope();
                    if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
                    }
                    Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {throw new IllegalStateException("No Scope registered for scope name'" + scopeName + "'");
                    }
                    try {Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);
                            try {return createBean(beanName, mbd, args);
                            }
                            finally {afterPrototypeCreation(beanName);
                            }
                        });
                        beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {throw new ScopeNotActiveException(beanName, scopeName, ex);
                    }
                }
            }
            catch (BeansException ex) {beanCreation.tag("exception", ex.getClass().toString());
                beanCreation.tag("message", String.valueOf(ex.getMessage()));
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
            finally {beanCreation.end();
            }
        }
                // 返回初始化胜利的对象,一个对象初始化就这样实现的了  
        return adaptBeanInstance(name, beanInstance, requiredType);  
    }

大略总结一下下面代码流程:

  • 先从三级缓存中获取,如果缓存中都没有。再去判断是否存在父容器,从父容器中获取。没有正式进入 bean 初始化流程,先依据 beanName 获取到 RootBeanDefinition,bean 类元信息、先解决 dependsOn 中 bean,保障 bean 依赖的创立程序,上面会阐明 org.springframework.context.annotation.@DependsOn 这个注解。下一步依照不同 scope 进行 bean 对象初始化。初始化流程就是这样,咱们将眼光放在单例 bean 如何实例化,集中关注AbstractAutowireCapableBeanFactory.createBean 获取注册一个单例对象

@DependsOn 注解意思是实例化某个对象依赖于某一个实例化,然而不须要持有这个实例对象。比方 bean A 上 须要依赖 bean b 能力实例化,然而 bean b 不须要作为他的属性,经常用于不同实例实例化程序标记。

看下 getSingleton 办法

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {if (this.singletonsCurrentlyInDestruction) { // 标记 bean 是否在销毁
                    throw new BeanCreationNotAllowedException(beanName,
                            "Singleton bean creation not allowed while singletons of this factory are in destruction" +
                            "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                }
                catch (IllegalStateException ex) { }
                catch (BeanCreationException ex) {throw ex;}
                finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}
                    afterSingletonCreation(beanName);
                }
                if (newSingleton) {addSingleton(beanName, singletonObject); // 就是在这里删除二三级缓存,提交到一级缓存
                }
            }
            return singletonObject;
        }
    }
    protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, singletonObject);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }

增加到一级缓存则阐明 bean 曾经实现实例化,能够失常应用了。上面看下如何进行实例化和属性注入的。

createBean

上面进入AbstractAutowireCapableBeanFactory.createBean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
        RootBeanDefinition mbdToUse = mbd;
        // 克隆一份 mbd => mbdToUse
        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 的代理对象,应用多个 BeanPostProcessors 来解决
            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 {
            // bean 对象实例化就这里实现
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {throw ex;}
        catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }

这里逻辑就比较简单了,克隆一份 RootBeanDefinition 用于初始化对象,resolveBeforeInstantiation 次要用于初始化代理对象状况,次要应用 BeanPostProcessor 子类 InstantiationAwareBeanPostProcessor 实现办法去实现对象初始化,并且在实例化胜利后在调用后置办法进行对象依赖注入,这里能够看见此办法返回对象间接跳出办法栈,这里能够看出单例和代理对象还是有区别的。单例对象初始化就在 doCreateBean 实现了

doCreateBean

上面就是 AbstractAutowireCapableBeanFactory.doCreateBean 十分靠近对象如何实例化的了

    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) {instanceWrapper = createBeanInstance(beanName, mbd, args);  // 这个就是实例化办法
        }
        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}

        // 应用 BeanDefinitionPostProcessors 对合并 bean 进行实例化 
        synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {
                try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

        // 这里就须要用到下面说的三级缓存常识了
        // even when triggered by lifecycle interfaces like BeanFactoryAware.
        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");
            }
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); // 将曾经实例化的对象退出到第三级缓存 singletonFactories 
        }

        // Initialize the bean instance.
        Object exposedObject = bean;
        try {populateBean(beanName, mbd, instanceWrapper); // 对属性进入注入,上面会具体分析的
            exposedObject = initializeBean(beanName, exposedObject, mbd); // 执行初始化办法,或者注入 Aware 接口 bean
        }
        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);
            }
        }

        // 上面代码省略
               // 次要就是对设置了 DisposableBean 接口销毁钩子办法解决
    }

这里代码次要分成三局部

  1. 初始化实例,创建对象实现,并且增加到 3 级缓存。第 3 级缓存经常用于存储代理对象,因为有些类须要动静代理办法,须要生成代理对象,会委派给第三级缓存办法 ObjectFactroy 去实现的,一般对象如果不须要会间接返回。
  2. 对实例化 bean 进行属性注入
  3. 执行初始化办法,DisposableBean 接口退出到 disposableBeans 容器中

instantiateBean

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // Make sure bean class is actually resolved at this point.
        Class<?> beanClass = resolveBeanClass(mbd, beanName);

        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
        }

        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {// 有实现 Supplier 接口,由 instanceSupplier.get() 办法创立实例
            return obtainFromSupplier(instanceSupplier, beanName);
        }

                //factoryName  应用工厂模式创立 bean,调用工厂办法去创立,这个反对静态方法和 factoryBean.invoke
        if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // Shortcut when re-creating the same bean...
        boolean resolved = false;   // 标记构造函数是否须要参数
        boolean autowireNecessary = false;  // 标记构造方法的参数是否应用注入形式
        if (args == null) {synchronized (mbd.constructorArgumentLock) {if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        if (resolved) {if (autowireNecessary) {
                               // 应用构造函数注入形式实例化
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                               // 实例化对象
                return instantiateBean(beanName, mbd);
            }
        }

        // 获取结构函数参数
        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);
    }

实例化办法 instantiateBean 最终会调用 SimpleInstantiationStrategy.instantiate 进行实例化

instantiate

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
        // Don't override the class with CGLIB if no overrides.
        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(); // 获取构造函数
                        }
                        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);
        }
    }

instantiateClass

    @Override
    public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
        // Don't override the class with CGLIB if no overrides.
        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();
                        }
                        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);
        }
    }

这里要留神下先判断 bean 是否有办法重写的,没有则应用反射生成的结构器,有就应用 gclib 形式创立代理对象,具体实现形式就在 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate,有趣味同学能够去学习下。
到此一个简略 bean 实例化实现了。

注入

上面进入 IOC 另一个特点,bean 注入,先从 AbstractAutowireCapableBeanFactory.populateBean 办法开始

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        // 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.postProcessAfterInstantiation 如果返回 true,指标实例外部的返回值会被 populate,否则 populate 这个过程会被忽视
            // 翻译说如果返回 true 能够执行字段注入 真的 6666 啊
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}
            }
        }

        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
                // 获取注入形式散布有 4 种
        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();
            // 依赖形式,模式都是没有类型查看,这种依赖形式个别都是 xml 配置用得比拟多,没有配置这里都是返回 false
        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);
            }
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }

        if (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

小知识点:
AutowireCapableBeanFactory.AUTOWIRE_NO 表明不会对以后 Bean 进行外部类的注入,惯例应用 @Autowire、@Resource 都是这类型
剩下三种都是通过 xml 或者 AutowireCapableBeanFactory.autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) 进行设置 autowireMode。

依据下面代码能够晓得主流程 bean 注入都是由 InstantiationAwareBeanPostProcessor 进行解决的, 简略阐明接口办法

办法 形容
postProcessBeforeInitialization 办法是最 先执行的办法,它在指标对象实例化之前调用,该办法的返回值类型是 Object,咱们能够返回任何类型的值。因为这个时候指标对象还未实例化,所以这个返回值能够用来代替本来该生成的指标对象的实例(比方代理对象)。如果该办法的返回值代替本来该生成的指标对象,后续只有 postProcessAfterInitialization 办法会调用,其它办法不再调用;否则依照失常的流程走
postProcessAfterInitialization 办法在指标对象实例化之后调用,这个时候对象曾经被实例化,然而该实例的属性还未被设置,都是 null。因为它的返回值是决定要不要调用 postProcessPropertyValues 办法的其中一个因素(因为还有一个因素是 mbd.getDependencyCheck());如果该办法返回 false, 并且不须要 check,那么 postProcessPropertyValues 就会被疏忽不执行;如果返回 true,postProcessPropertyValues 就会被执行
postProcessPropertyValues 对 bean 属性值赋值后调用,对属性值的批改。如果 postProcessAfterInstantiation 办法返回 false,该办法可能不会被调用。能够在该办法内对属性值进行批改
postProcessProperties Bean 属性赋值就是调用这个办法的

InstantiationAwareBeanPostProcessor 接口实现类次要分 3 个

  1. ConfigurationClassPostProcessor:看类名就晓得解决 @Configuration 实例化,并没有属性注入逻辑,不详讲略过。
  2. CommonAnnotationBeanPostProcessor:这个类就是实现 bean 注入,然而是实现 JSR-250 注解、@Resource,@EJB、@WebServiceRef,@WebServiceContext,@PostConstrusct、@PreDestory 这些注解实现。
  3. AutowiredAnnotationBeanPostProcessor:实现 @Autowired、@Value 注入, 并且反对 JSR-330’s @Inject, 次要剖析这个类就能够晓得 bean 注入的。

AutowiredAnnotationBeanPostProcessor 剖析

    private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
    @SuppressWarnings("unchecked")
    public AutowiredAnnotationBeanPostProcessor() {this.autowiredAnnotationTypes.add(Autowired.class);
        this.autowiredAnnotationTypes.add(Value.class);
        try {this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
                    ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
            logger.trace("JSR-330'javax.inject.Inject'annotation found and supported for autowiring");
        }
        catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}
    }

在初始化时就将反对注解退出汇合中,再应用扫描器去扫描办法、结构器、字段,如果有这些注解就进行注入。

看下怎么判断是否须要注入的

    @Nullable
    private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {MergedAnnotations annotations = MergedAnnotations.from(ao);
        for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {MergedAnnotation<?> annotation = annotations.get(type);
            if (annotation.isPresent()) {return annotation;}
        }
        return null;
    } 

AccessibleObject 是 Method、Field、Constructor 父类。

postProcessProperties 如何实现 bean 注入的
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
              // 获取须要注入字段,办法
        InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
        try {metadata.inject(bean, beanName, pvs); // 注入
        }
        catch (BeanCreationException ex) {throw ex;}
        catch (Throwable ex) {throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
        }
        return pvs;
    }
       // 上面就行获取 InjectionMetadata 
    private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
        // Fall back to class name as cache key, for backwards compatibility with custom callers.
        String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
        // 疾速从缓存中获取,如果没有加锁去解析,而后在后果放入缓存中
        InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
        if (InjectionMetadata.needsRefresh(metadata, clazz)) {synchronized (this.injectionMetadataCache) { // 双重查看
                metadata = this.injectionMetadataCache.get(cacheKey);
                if (InjectionMetadata.needsRefresh(metadata, clazz)) {if (metadata != null) {metadata.clear(pvs);
                    }
                    metadata = buildAutowiringMetadata(clazz); 
                    this.injectionMetadataCache.put(cacheKey, metadata); 
                }
            }
        }
        return metadata;
    }
  • InjectionMetadata 次要是汇合 bean 须要被注入类型,因为曾经解析过 bean Class 信息了,相当于解析后果装起来

看下如何去扫描办法、字段的

     private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
       // 从给定注解中判断 class 是否携带这个注解
        if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {return InjectionMetadata.EMPTY;}

        List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
        Class<?> targetClass = clazz;

        do {final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
            // 遍历所有 Field,找出扫描的注解,特意标注不反对 static 润饰 field 
            ReflectionUtils.doWithLocalFields(targetClass, field -> {MergedAnnotation<?> ann = findAutowiredAnnotation(field);
                if (ann != null) {if (Modifier.isStatic(field.getModifiers())) {if (logger.isInfoEnabled()) {logger.info("Autowired annotation is not supported on static fields:" + field);
                        }
                        return;
                    }
                     // 获取注解内 required 值
                    boolean required = determineRequiredStatus(ann);
                    currElements.add(new AutowiredFieldElement(field, required));
                }
            });

            ReflectionUtils.doWithLocalMethods(targetClass, method -> {
                // 获取办法上桥接办法,因为泛型类型擦除,要对桥接办法进行安全检查,避免在调用是出现异常
                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
                if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {return;}
                // 获取注解
                MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
               // 办法安全检查
                if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {if (Modifier.isStatic(method.getModifiers())) { // 不反对静态方法注入
                        if (logger.isInfoEnabled()) {logger.info("Autowired annotation is not supported on static methods:" + method);
                        }
                        return;
                    }
                    if (method.getParameterCount() == 0) {if (logger.isInfoEnabled()) {
                            logger.info("Autowired annotation should only be used on methods with parameters:" +
                                    method);
                        }
                    }
                    boolean required = determineRequiredStatus(ann);
                    PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
                    currElements.add(new AutowiredMethodElement(method, required, pd));
                }
            });
           // 这样写是为了前面退出排在队列后面,父类属性优先于子类
            elements.addAll(0, currElements);
            targetClass = targetClass.getSuperclass();}
        while (targetClass != null && targetClass != Object.class); // 这里写得很好,向上解析父类,直到是 Object 为止

        return InjectionMetadata.forElements(elements, clazz);
    }

逻辑非常简单,就是依据给定注解去 class 获取指定的注解,从而获取到须要注入类型,然而几行简略的代码能够看出弱小编码能力,学习了👍。
当初须要注入对象曾经获取到,看如何注入吧

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        Collection<InjectedElement> checkedElements = this.checkedElements;
        Collection<InjectedElement> elementsToIterate =
                (checkedElements != null ? checkedElements : this.injectedElements);
        if (!elementsToIterate.isEmpty()) {for (InjectedElement element : elementsToIterate) {element.inject(target, beanName, pvs);
            }
        }
    }

        @Override
        protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {Field field = (Field) this.member;
            Object value;
            if (this.cached) {
                try {value = resolvedCachedArgument(beanName, this.cachedFieldValue);
                }
                catch (NoSuchBeanDefinitionException ex) {
                    // Unexpected removal of target bean for cached argument -> re-resolve
                    value = resolveFieldValue(field, bean, beanName);
                }
            }
            else {value = resolveFieldValue(field, bean, beanName);
            }
            if (value != null) {ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
            }
        }

        private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
            desc.setContainingClass(bean.getClass());
            Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
            Assert.state(beanFactory != null, "No BeanFactory available");
            TypeConverter typeConverter = beanFactory.getTypeConverter(); // 类型转换器
            Object value;
            try {value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
            }
            catch (BeansException ex) {throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
            }
            synchronized (this) {if (!this.cached) {
                    Object cachedFieldValue = null;
                    if (value != null || this.required) {
                        cachedFieldValue = desc;
                        // 将注入关系增加到容器中,不便 bean 销毁时同步销毁
                        registerDependentBeans(beanName, autowiredBeanNames);
                        if (autowiredBeanNames.size() == 1) {String autowiredBeanName = autowiredBeanNames.iterator().next();
                            if (beanFactory.containsBean(autowiredBeanName) &&
                                    beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { // 这些都是为了缓存起来
                                cachedFieldValue = new ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType());
                            }
                        }
                    }
                    this.cachedFieldValue = cachedFieldValue;
                    this.cached = true;
                }
            }
            return value;
        }
    }

次要外围是如从缓存获取到须要注入类型实例在 beanFactory.resolveDependency
进入 DefaultListableBeanFactory 看下

    public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
        if (Optional.class == descriptor.getDependencyType()) {return createOptionalDependency(descriptor, requestingBeanName);
        }
        else if (ObjectFactory.class == descriptor.getDependencyType() ||
                ObjectProvider.class == descriptor.getDependencyType()) {return new DependencyObjectProvider(descriptor, requestingBeanName);
        }
        else if (javaxInjectProviderClass == descriptor.getDependencyType()) {return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
        }
        else {
                        // 懒加载  扫描 @Lazy 注解,返回一个代理对象
            Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
            if (result == null) {result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
            }
            return result;
        }
    }

@Lazy 应用注解润饰 bean 或者 Class,在容器初始化化时不会立即创立,只有须要应用 bean 才会创立的。
依据类型 Optional、ObjectFactory、Provider,还有懒加载情景不同的解决,这些解决实质都是要调用 doResolveDependency 办法初始化对象,无论那种对象都要 获取原始对象而后再交给这些接口去包装加强。

    public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
            // 如果这个注入是通过结构器注入,能够从结构器解析缓存中去获取注入信息点    
        InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
        try {Object shortcut = descriptor.resolveShortcut(this);
            if (shortcut != null) {return shortcut;}

            Class<?> type = descriptor.getDependencyType();
                     // 尝试从注解中获取默认值   @Value  的 value  
            Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
            if (value != null) {if (value instanceof String) {String strVal = resolveEmbeddedValue((String) value);
                    BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                            getMergedBeanDefinition(beanName) : null);
                    value = evaluateBeanDefinitionString(strVal, bd);
                }
                TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
                try {return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
                }
                catch (UnsupportedOperationException ex) {
                    // A custom TypeConverter which does not support TypeDescriptor resolution...
                    return (descriptor.getField() != null ?
                            converter.convertIfNecessary(value, type, descriptor.getField()) :
                            converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
                }
            }
              // 多种混合类型解决,stream、collection、Map Array 这些
            Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
            if (multipleBeans != null) {return multipleBeans;}

                  // 依据类型获取容器中 bean 名,返回 map key 就是 bean 名,value 初始从容器中获取对象,如果没有找到就会抛出异样了
            Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
            if (matchingBeans.isEmpty()) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
                }
                return null;
            }

            String autowiredBeanName;
            Object instanceCandidate;

            if (matchingBeans.size() > 1) {  // 呈现一个类型,不同实例,能够依据 @Primary, @Priority、属性名形式去配置
                autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
                if (autowiredBeanName == null) {if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {  // 没有确定,抛出异样
                        return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
                    }
                    else {return null;}
                }
                instanceCandidate = matchingBeans.get(autowiredBeanName);
            }
            else {
                // We have exactly one match.
                Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
                autowiredBeanName = entry.getKey();
                instanceCandidate = entry.getValue();}

            if (autowiredBeanNames != null) {autowiredBeanNames.add(autowiredBeanName);
            }
            if (instanceCandidate instanceof Class) {  // 这里其实就是从容器中获取实例,如果这时候没有初始化,就走下面初始化流程
                instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
            }
            Object result = instanceCandidate;
            if (result instanceof NullBean) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
                }
                result = null;
            }
            if (!ClassUtils.isAssignableValue(type, result)) {throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
            }
            return result;
        }
        finally {ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
        }
    }

这个办法简略做个总结,先是解决 @Value 状况,而后通过 findAutowireCandidates 通过类型去容器中获取实例,如何实例还没有初始化,就会调用下面那个初始化过程,将初始化对象返回。依据注入类型进行相应解决,像 stream、Collection,这些混合类型都是间接增加进去。如果呈现了一个类型多个 bean 状况,这时就是就是 @Primary、@Priority 这些注解来判断或者依据属性名去和 beanName 匹配,最初将 bean 对象返回。
这里就简略看完一个 bean 初始化流程了。

总结

当初晓得了 Bean 实例化是由一个策略模式,应用反射攻打类创立的,和 BeanPostProcessor 其实并没有太多关系的。像我刚开始学 spring 时,老师就说 @Autowired 和 @Resources 向比拟,基于类型和 beanName 进行注入的,这样说不完全正确的。他是通过类型去获取 bean,如果呈现一个类型有多个 beanName,才通过 bean 和属性名进行注入。应用这么多年 Spring 了,素来没有应用过 @DependsOn、@Primary、@Priority、@Lookup 如果不看源码还不晓得有这个个性呢。看残缺个源码,对 bean 生命周期有了比拟清晰 bean 实例化 -> 属性注入 -> 执行初始化办法 -> 退出 spring 容器

正文完
 0