• springboot笔记-3-.实例化bean


    前言

      前面几章spring已经把需要的注册的bean的信息已经全部加载到了BeanFactory中了,那么之后要做的事儿当然就是进行实例化了,当然了可能有人会问为何不在加载到bean信息的时候直接进行实例化呢,这不还需要依赖注入嘛,当然是要所有的都加载完了才能实例化。ApplicationContext相对于BeanFactory来说,早期的BeanFactory受制于硬件配置,所以在我们需要某个bean的时候才会进行实例化。而ApplicationContext则会在一开始就将所有的注册的Bean(标记懒加载的,或者非单例加载除外)全部进行实例化。本文则主要介绍spring如何实例化bean,并且Bean的生命周期也会穿插其中。

    这儿先放一张加载的大致流程图

      从图中可以看到加正式加载的过程并不多,实例化->放入提前暴露容器->赋值完成后其实就算完成实例化了,但spring在其中穿插了 很多的BeanPostProcessor以及aware,同时也会根据所加载bean是否实现了InitializingBean接口来决定是否需要执行afterPropertiesSet方法。说明spring在实例化bean时给我们流下了足够的扩展空间。

    正文

      我们回到上下文的refresh方法中

    public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                ../代码略
    
                try {
                    postProcessBeanFactory(beanFactory);
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // 注册所有BeanPostProcessors
                    registerBeanPostProcessors(beanFactory);
    
                    ../代码略
    
                    //实例化bean
                    finishBeanFactoryInitialization(beanFactory);
                    ../代码略
                }
    
                ../代码略
            }
        }

      前面一篇我们成功的执行了invokeBeanFactoryPostProcessors方法,然后将所有的BeanFactoryPostProcessor后置方法执行了,然后也成功的将所有需要注册到容器的bean的BeanDefination也收集到了BeanFactory中。本文则主要关注后面两个方法。

    • registerBeanPostProcessors  按照一定顺序注册BeanPostProcessor
    • 实例化所有的bean  

      至于注册BeanPostProcessor较为简单,就是将系统所有的BeanPostProcessor按照顺序,即我们之前也遇到的三级顺序来添加,实现了PriorityOrdered为第一级,实现了Ordered为第二级,其他的为第三级。具体添加过程较为简单所以代码部分略过,我们直接看实例化bean的方法

    1.finishBeanFactoryInitialization 实例化的入口

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
            // 初始化一个ConversionService
            if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                    beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
                beanFactory.setConversionService(
                        beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
            }
    
            // 初始化一个默认的EmbeddedValueResolver(如果系统没有指定的话)
            if (!beanFactory.hasEmbeddedValueResolver()) {
                beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
            }
    
            // 实例化LoadTimeWeaverAware   getBean方法会触发实例化
            String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
            for (String weaverAwareName : weaverAwareNames) {
                getBean(weaverAwareName);
            }
    
            // Stop using the temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(null);
    
            //实例化之前冻结配置
            beanFactory.freezeConfiguration();
    
            // 实例化所有非懒加载的实例  
            beanFactory.preInstantiateSingletons();
    }

      这儿就是做了一些必要的提前设置。这儿我们进入beanFactory.preInstantiateSingletons方法,注意这儿的beanFactory一般为DefaultListableBeanFactory,本系列第二章初始化应用上下文有讲到

    2.preInstantiateSingletons

      顾名思义,看方法名就知道是实例化之前的一些准备,看代码

      

    @Override
        public void preInstantiateSingletons() throws BeansException {
            //打印下日志
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Pre-instantiating singletons in " + this);
            }
    
            //迭代spring找到的所有需要注册的bean
            List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
            //开始迭代
            for (String beanName : beanNames) {
                
                //获取该bean对应的mergedBeanDefinition  
                //如果没有则获取其父类的MergedLocalBeanDefinition  
                //如果父类为空则创建RootBeanDefinition
                RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
                //如果不是抽象类   且是单例构造  非懒加载  则实例化
                if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                    //如果该bean是FactoryBean
                    if (isFactoryBean(beanName)) {
                        //如果是FactoryBean则要判断下其是否需要提早初始化
                        Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                        if (bean instanceof FactoryBean) {
                            final FactoryBean<?> factory = (FactoryBean<?>) bean;
                            boolean isEagerInit;
                            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                                isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                                ((SmartFactoryBean<?>) factory)::isEagerInit,
                                        getAccessControlContext());
                            }
                            else {
                                isEagerInit = (factory instanceof SmartFactoryBean &&
                                        ((SmartFactoryBean<?>) factory).isEagerInit());
                            }
                            if (isEagerInit) {
                                getBean(beanName);
                            }
                        }
                    }
                    else {
                    //非factoryBean      初始化
                        getBean(beanName);
                    }
                }
            }
    
            // 如果为SmartInitializingSingleton类型  则执行下其初始化完成后的afterSingletonsInstantiated方法
            for (String beanName : beanNames) {
                Object singletonInstance = getSingleton(beanName);
                if (singletonInstance instanceof SmartInitializingSingleton) {
                    final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                    if (System.getSecurityManager() != null) {
                        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                            smartSingleton.afterSingletonsInstantiated();
                            return null;
                        }, getAccessControlContext());
                    }
                    else {
                        smartSingleton.afterSingletonsInstantiated();
                    }
                }
            }
        }

      方法也就是获取我们之前得到的beanDefinitionNames,然后挨个遍历,如果其不为抽象类,且是单例加载,非延迟加载,那我们就对其进行实例化。然后根据beanName获取其合并的BeanDefinition,也就是其BeanDefinition一直递归加上其父类的BeanDefinition,最终合并为一个RootBeanDefinition并返回,具体的这儿的分析可以查看这篇博客。https://blog.csdn.net/andy_zhang2007/article/details/86514320

      获取到合并的beanDefinition后,检查其是否满足加载的条件。这儿可以看出springboot满足初始化即加载的条件主要由两:单例记载,非懒加载。

      然后会判断当前迭代的bean是否是FactoryBean,如果是则进行特殊判断处理下,这儿二者最终都会调用getBean方法来创建类。创建完成后如果该bean实现了SmartInitializingSingleton接口,则会执行下其afterSingletonsInstantiated方法。

      其getBean方法是主要的创建方法,其实看到这儿也能发现。ApplicationContext方法的初始即实例化最终也是循环调用的BeanFactory的getBean方法。

    3.getBean

    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
                @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
            
            //获取beanName
            final String beanName = transformedBeanName(name);
            Object bean;
    
            // 找下是否已经创建过
            Object sharedInstance = getSingleton(beanName);
            //如果已经开始创建且参数为空就不再执行创建逻辑了
            //这儿创建中分为了两种情况
            if (sharedInstance != null && args == null) {
                if (logger.isDebugEnabled()) {
                    //如果该类创建中,但还未创建完成
                    if (isSingletonCurrentlyInCreation(beanName)) {
                        logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                                "' that is not fully initialized yet - a consequence of a circular reference");
                    }
                    //已经创建完成
                    else {
                        logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                    }
                }
                //直接拿出来并返回
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
            }
            //这儿则是创建流程
            else {
                //重复声明时有可能出现此问题
                if (isPrototypeCurrentlyInCreation(beanName)) {
                    throw new BeanCurrentlyInCreationException(beanName);
                }
    
                //查看父BeanFactory是否已经有了 如果有的话则返回父BeanFactory中的实例
                BeanFactory parentBeanFactory = getParentBeanFactory();
                if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                    // Not found -> check parent.
                    String nameToLookup = originalBeanName(name);
                    if (parentBeanFactory instanceof AbstractBeanFactory) {
                        return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                                nameToLookup, requiredType, args, typeCheckOnly);
                    }
                    else if (args != null) {
                        // Delegation to parent with explicit args.
                        return (T) parentBeanFactory.getBean(nameToLookup, args);
                    }
                    else {
                        // No args -> delegate to standard getBean method.
                        return parentBeanFactory.getBean(nameToLookup, requiredType);
                    }
                }
                //标记该bean已经在开始被实例化
                if (!typeCheckOnly) {
                    markBeanAsCreated(beanName);
                }
    
                try {
                    //获取合并BeanDefinition
                    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                    //检查下合并BeanDefinition  这儿主要检查是否为抽象类
                    checkMergedBeanDefinition(mbd, beanName, args);
    
                    // 获取该bean的构造函数的参数
                    //如果该bean构造函数中依赖的参数中,有参数实例化也需要依赖该bean 那么直接报循环引用的错误
                    String[] dependsOn = mbd.getDependsOn();
                    if (dependsOn != null) {
                        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);
                            }
                        }
                    }
    
                    // 如果为scope为sington  那么只创建一个
                    if (mbd.isSingleton()) {
                        sharedInstance = getSingleton(beanName, () -> {
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            catch (BeansException ex) {
                                // Explicitly remove instance from singleton cache: It might have been put there
                                // eagerly by the creation process, to allow for circular reference resolution.
                                // Also remove any beans that received a temporary reference to the bean.
                                destroySingleton(beanName);
                                throw ex;
                            }
                        });
                        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                    }
                    // 如果为scope为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);
                        }
                        bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                    }
                    //如果都不是 比如是自定义的  那就根据自定义的逻辑创建
                    else {
                        String scopeName = mbd.getScope();
                        final 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);
                                }
                            });
                            bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                        }
                        catch (IllegalStateException ex) {
                            throw new BeanCreationException(beanName,
                                    "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                    "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                    ex);
                        }
                    }
                }
                catch (BeansException ex) {
                    cleanupAfterBeanCreationFailure(beanName);
                    throw ex;
                }
            }
    
            // 如果有合适的Converter  那么执行下converter转换器的操作 返回转换后的实例
            if (requiredType != null && !requiredType.isInstance(bean)) {
                try {
                    T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                    if (convertedBean == null) {
                        throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                    }
                    return convertedBean;
                }
                catch (TypeMismatchException ex) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Failed to convert bean '" + name + "' to required type '" +
                                ClassUtils.getQualifiedName(requiredType) + "'", ex);
                    }
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
            }
            return (T) bean;
        }

      该方法内容较多,但可以分步看

    1. 判断是否已经创建中并能获取实例,如果可以就返回,否则下一步
    2. 判断一下重复加载的问题,然后查看父BeanFactory是否有该类,如果有则使用父类的getBean返回,否则下一步
    3. 判断下循环循环引用的问题,如果构造函数有参数,但不存在循环引用,则先实例化构造参数
    4. 最终根据bean的scope来确定不同的初始化方式
    5. 根据初始化完成后的bean来寻找是否有合适的converter,如果有则转换后返回,否则直接返回

      这样拆开看发现也就是spring很常规的一个判断逻辑,由于不同scope只是创建的数量不一致,但是实例化bean是一致的,所以我们就直接看实例化singleton,也就是我们最常见的单例注册。

    4.单例化代码的片段

      上面的代码中,我们着重看下创建单例的代码片段。

    if (mbd.isSingleton()) {
        //获取创建后的实例
        sharedInstance = getSingleton(beanName, () -> {
            try {
                //回调函数创建bean
                return createBean(beanName, mbd, args);
            }
            catch (BeansException ex) {
                //出现异常则将其销毁
                destroySingleton(beanName);
                throw ex;
            }
        });
        //看当前的bean是一个普通的bean还是beanFactory 
        //如果是普通的bean直接返回
        //如果是factoryBean则返回其getObject方法的结果
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }

      这儿可以看到通过getSingletom方法获取bean,这个方法有个回调函数是用来创建bean的,可以得知具体创建bean的时机肯定是getSingleton中调用这个函数的时候。getSingletom则只是做了一些前后处理。那我们还是先看下回调函数中的createBean方法,毕竟这才是核心创建过程。

    5.createBean

      

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
                throws BeanCreationException {
    
            //获取该bean的合并BeanDefinition
            RootBeanDefinition mbdToUse = mbd;
    
            //查看当前RootBeanDefinition是否已经有resolveBeanClass  如果有的话直接clone一个beanDefinition
            Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
            if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
                mbdToUse = new RootBeanDefinition(mbd);
                mbdToUse.setBeanClass(resolvedClass);
            }
    
            //检查下所有的override方法
            try {
                mbdToUse.prepareMethodOverrides();
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                        beanName, "Validation of method overrides failed", ex);
            }
    
            try {
                // 执行所有实现了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法
                // 这儿如果返回不为null  则就是自定义了返回的bean逻辑
                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 {
                //执行doCreateBean创建bean
                Object beanInstance = doCreateBean(beanName, mbdToUse, args);
                if (logger.isDebugEnabled()) {
                    logger.debug("Finished creating instance of bean '" + beanName + "'");
                }
                return beanInstance;
            }
            ../代码省略
    }

      该方法内部照例做了一下准备,其中有个方法需要注意resolveBeforeInstantiation ,该方法会在实例化之前执行所有实现了InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法,如果返回值不为空则代表自定义了类实例化过程,这样会直接返回bean而不会进行下面的所有操作

      然后执行doCreateBean创建实例对象。

    6.doCreateBean

      

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
                throws BeanCreationException {
    
            // 实例化bean 如果factoryBeanInstance已经有了则将其remove掉
            BeanWrapper instanceWrapper = null;
            if (mbd.isSingleton()) {
                instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
            }
            if (instanceWrapper == null) {
                //创建实例
                instanceWrapper = createBeanInstance(beanName, mbd, args);
            }
            final Object bean = instanceWrapper.getWrappedInstance();
            Class<?> beanType = instanceWrapper.getWrappedClass();
            //检查下创建出来的bean是否为null,例如我们从beanFactory中get为null  或者@Bean方法返回为null
            if (beanType != NullBean.class) {
                mbd.resolvedTargetType = beanType;
            }
    
            // 执行所有实现了MergedBeanDefinitionPostProcessor接口的类的postProcessMergedBeanDefinition方法
            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;
                }
            }
    
            //如果允许属性值循环依赖,则将实例其放入一个singletonFactories缓存中,此时该类已经实例化但还未为属性赋值
            //如果该类依赖的属性值实例化时依赖该类,那么就可以从这个singletonFactories提前拿到还未赋值的属性值实例
            boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                    isSingletonCurrentlyInCreation(beanName));
            if (earlySingletonExposure) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Eagerly caching bean '" + beanName +
                            "' to allow for resolving potential circular references");
                }
                addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
            }
    
            
            Object exposedObject = bean;
            try {
                // 为实例赋属性值
                populateBean(beanName, mbd, instanceWrapper);
                //执行一些列初始化方法
                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);
                if (earlySingletonReference != null) {
                    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);
                            }
                        }
                        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 " +
                                    "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                        }
                    }
                }
            }
    
            // 如果bean是一次性的则将其注入一次性使用容器中
            try {
                registerDisposableBeanIfNecessary(beanName, bean, mbd);
            }
            catch (BeanDefinitionValidationException ex) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
            }
    
            return exposedObject;
        }

      该方法有几个地方需要注意

    1. 实例化bean后检查了该bean是否为null
    2. 执行了所有实现了实现了MergedBeanDefinitionPostProcessor接口的类的postProcessMergedBeanDefinition方法
    3. 如果出现了属性值循环引用,且允许循环引用,那么会将实例化好但还未赋值的bean放入一个singletonFactories提前暴露容器中来解决属性值循环引用
    4. 然后在为属性赋值
    5. 然后执行初始化方法。

      我们则简要分析下这几个步骤

    6.1createBeanInstance创建实例

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
            // 确保beanClass可以被实例化  例如其是否为public   
            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  如果有直接返回
            Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
            if (instanceSupplier != null) {
                return obtainFromSupplier(instanceSupplier, beanName);
            }
            //查看该类是否为@Bean方法初始化  如果是的话执行方法逻辑
            if (mbd.getFactoryMethodName() != null)  {
                return instantiateUsingFactoryMethod(beanName, mbd, args);
            }
    
            // Shortcut when re-creating the same bean...
            boolean resolved = false;
            boolean autowireNecessary = false;
            //如果初始化构造参数为null且能找到构造函数或者FactoryMethod(如果为factoryBean)
            if (args == null) {
                synchronized (mbd.constructorArgumentLock) {
                    if (mbd.resolvedConstructorOrFactoryMethod != null) {
                        resolved = true;
                        //查看其是否有@Autowired的参数
                        autowireNecessary = mbd.constructorArgumentsResolved;
                    }
                }
            }
            if (resolved) {
                //如果有@Autowaired参数则执行这个autowireConstructor方法
                if (autowireNecessary) {
                    return autowireConstructor(beanName, mbd, null, null);
                }
                //如果没有则执行instantiateBean方法
                else {
                    return instantiateBean(beanName, mbd);
                }
            }
    
            //如果上面没找到有效的构造函数  就从BeanPostProcessor中查找 然后执行返回
            Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
            if (ctors != null ||
                    mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
                    mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
                return autowireConstructor(beanName, mbd, ctors, args);
            }
    
            // No special handling: simply use no-arg constructor.
            return instantiateBean(beanName, mbd);
        }

      这儿步骤主要为   

         1.校验是否能实例化 

         2.是否有定制的supplier,有则返回 

         3.是否为@Bean初始化,如果是则执行专门的实例化方法 

         4.如果传入的构造参数为null,则根据自动注入的参数或者无参的方法来实例化。

         5.如果传入的参数不为null  或者需要的参数里有不是自动注入的,那么根据BeanPostProcessor找到合适的构造函数并实例化

      这儿具体的对象创建过程由于篇幅就不讲解了,可以根据各个方法进去仔细查看,不过大概能想到的应该就是根据传入的参数反射创建实例,如果是@Bean方法创建的话应该是反射执行方法创建,如果需要代理的话则创建代理对象并返回。

    6.2 applyMergedBeanDefinitionPostProcessors

      这也是springBean生命周期中的一个重要步骤

        protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof MergedBeanDefinitionPostProcessor) {
                    MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
                    bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
                }
            }
        }

      该方法会执行所有的MergedBeanDefinitionPostProcessor 的postProcessMergedBeanDefinition方法。

    6.3 处理属性值循环引用addSingletonFactory

    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

        这儿注意getEarlyBeanReference又会执行所有实现了SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法。

      此处其实就是利用了一个提前暴露的singletonFactories容器,将实例化但还未赋值的bean放置在其中,当循环引用的bean需要用到这个bean时就可以拿到还未赋值的bean。即可解决属性值循环引用的问题。

        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); //singletonFactories 提前暴露的Factories容器
                    this.earlySingletonObjects.remove(beanName);//singletonFactories 提前暴露的bean容器
                    this.registeredSingletons.add(beanName);// 已注册的单例容器
                }
            }
        }

      注意这儿有两个容器都涉及到提前引用  ,区别是earlySingletonObjects 放置的实例化的bean   而singletonFactories 放置的是实例化的bean的包装。之所以加个包装是为了获取提前暴露的引用时可以执行SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法。

        /** Cache of singleton factories: bean name --> ObjectFactory */
        private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    
        /** Cache of early singleton objects: bean name --> bean instance */
        private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

      具体的处理循环引用的逻辑文章最后会单独说下,这儿注意get

    6.4 为属性赋值

    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;
                }
            }
    
            //检查下是否需要赋值 如果有某个InstantiationAwareBeanPostProcessor返回未false   那么就跳过赋值操作
            boolean continueWithPropertyPopulation = true;
    
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            continueWithPropertyPopulation = false;
                            break;
                        }
                    }
                }
            }
    
            if (!continueWithPropertyPopulation) {
                return;
            }
            //获取要赋值的属性值
            PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
            
            //根据不同的来不同的注入
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
                    mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    
                // by name 例如@Resources
                if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                    autowireByName(beanName, mbd, bw, newPvs);
                }
    
                // by type 例如@Autowied
                if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                    autowireByType(beanName, mbd, bw, newPvs);
                }
    
                pvs = newPvs;
            }
    
            boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
            boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
            //如果有对应的InstantiationAwareBeanPostProcessors则执行下其postProcessPropertyValues方法
            if (hasInstAwareBpps || needsDepCheck) {
                if (pvs == null) {
                    pvs = mbd.getPropertyValues();
                }
                PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                if (hasInstAwareBpps) {
                    for (BeanPostProcessor bp : getBeanPostProcessors()) {
                        if (bp instanceof InstantiationAwareBeanPostProcessor) {
                            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                            pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                            if (pvs == null) {
                                return;
                            }
                        }
                    }
                }
                if (needsDepCheck) {
                    checkDependencies(beanName, mbd, filteredPds, pvs);
                }
            }
    
            if (pvs != null) {
                //将找到的属性值赋上
                applyPropertyValues(beanName, mbd, bw, pvs);
            }
        }

      该方法检查了下bean是否为空,和该bean是否需要赋值,然后找到了所有的InstantiationAwareBeanPostProcessor执行了下其postProcessPropertyValues (如果需要的话),最后将找到的值赋上。

    6.5 初始化方法initializeBean

      bean实例化后会执行initializeBean方法。该方法会执行很多bean生命周期相关的方法。

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }, getAccessControlContext());
            }
            else {
                //1.执行所有实现了BeanNameAware的setBeanName方法
                //2.执行所有实现了BeanClassLoaderAware的setBeanClassLoader方法
                //3.执行所有实现了BeanFactoryAware的setBeanFactory方法
                invokeAwareMethods(beanName, bean);
            }
    
            Object wrappedBean = bean;
            if (mbd == null || !mbd.isSynthetic()) {
                //执行所有实现了BeanPostProcessor的postProcessBeforeInitialization方法
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }
    
            try {
                //如果该类实现了InitializingBean接口,则执行afterPropertiesSet方法
                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()) {
                //执行所有实现了BeanPostProcessor的postProcessAfterInitialization方法
                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
            }
    
            return wrappedBean;
        }

      该方法会执行很多的spring生命周期的方法,首先会执行一堆的aware前置方法。然后执行BeanPostProcessor的postProcessBeforeInitialization,然后如果该类实现了InitializingBean则执行afterPropertiesSet方法,最后执行BeanPostProcessor的postProcessAfterInitialization方法(该方法可以关注下,spring aop功能正是基于此实现的)。此时创建bean的工作已经基本完成了。

    7.回到getSingleton

      上面所讲的都是ObjectFactory的回调函数的实现内容,那么调用的时机,和调用的前后逻辑还需要我们了解一下。即本文第4节的getSingtone方法。

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
            Assert.notNull(beanName, "Bean name must not be null");
            synchronized (this.singletonObjects) {
                //看下singletonObject中是否已经有了 如果没有进入创建
                Object singletonObject = this.singletonObjects.get(beanName);
                if (singletonObject == null) {
                    //校验一下是否正在创建中,如果正在创建中直接抛异常
                    if (this.singletonsCurrentlyInDestruction) {
                        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!)");
                    }
                    if (logger.isDebugEnabled()) {
                        logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
                    }
                    
                    //将当前bean加入singletonsCurrentlyInCreation容器
                    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) {
                        // Has the singleton object implicitly appeared in the meantime ->
                        // if yes, proceed with it since the exception indicates that state.
                        singletonObject = this.singletonObjects.get(beanName);
                        if (singletonObject == null) {
                            throw ex;
                        }
                    }
                    catch (BeanCreationException ex) {
                        if (recordSuppressedExceptions) {
                            for (Exception suppressedException : this.suppressedExceptions) {
                                ex.addRelatedCause(suppressedException);
                            }
                        }
                        throw ex;
                    }
                    finally {
                        if (recordSuppressedExceptions) {
                            this.suppressedExceptions = null;
                        }
                        //从singletonsCurrentlyInCreation容器中移除该bean
                        afterSingletonCreation(beanName);
                    }
                    if (newSingleton) {
                        //将该bean添加到singletonObjects容器中  并从提前暴露的容器中移除
                        addSingleton(beanName, singletonObject);
                    }
                }
                return singletonObject;
            }
        }

      可以看到该类中主要核查防止了重复加载,然后通过回调函数获取我们创建的bean后,将其从提前暴露的容器中移除,然后放入BeanFactory的真正的bean容器中。此时一个bean就算被创建完成已经可以正式使用了。

      可以发现其中执行了很多的BeanPostProcessor和aware,这也是spring对bean的扩展性做的极高的一种体现。

      到此spring初始化一个bean已经成功了。有关spring的具体加载流程简要图已经在一开始给出,可以对照着查看。而且spring的bean的生命周期除了销毁部分,其他的基本就是上述的内容。

    后记

      关于spring解决属性循环依赖的问题主要是如下的代码。

        protected Object getSingleton(String beanName, boolean allowEarlyReference) {
            //如果未从singletonObjects获取到就要尝试从提前暴露的容器中拿
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
                synchronized (this.singletonObjects) {
                    //从提前暴露的容器中拿singletonObject
                    singletonObject = this.earlySingletonObjects.get(beanName);
                    //如果也为空
                    if (singletonObject == null && allowEarlyReference) {
                        //那么尝试从提前暴露的包装容器中拿
                        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                            //如果包装容器不为空,那么就拿到其引用 然后添加到提前暴露容器中 并从提前暴露的包装容器中移除
                            singletonObject = singletonFactory.getObject();
                            this.earlySingletonObjects.put(beanName, singletonObject);
                            this.singletonFactories.remove(beanName);
                        }
                    }
                }
            }
            return singletonObject;
        }

      可以看到在获取bean时如果没获取到会尝试从提前暴露容器中获取,如果还是获取不到就从提前暴露的包装容器中获取。如果能获取到就将其从包装容器中移除,设置到容器中。

     

  • 相关阅读:
    Facebook第三方登录切换账号的问题
    内部类中调用外部变量
    前端还原UI设计图CSS样式工具(ps+蓝湖+PxCook+imgcook)
    git 报错 eslint fix found some errors. Please fix them and try committing again.
    在vue中使用vuebaidumap实现地址定位标点及关键字搜索定位(获取地址数据并获取经纬度)
    elementui的时间范围组件,限制选了第一个时间后,第二个只能在第一个的前后一周
    JavaScript API v2.0+ v3.0
    BFC块级格式化上下文
    解决小程序api无法返回promise对象
    移动端适配 视口(viewport)和vw、vh、rem
  • 原文地址:https://www.cnblogs.com/hetutu-5238/p/12394806.html
Copyright © 2020-2023  润新知