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时如果没获取到会尝试从提前暴露容器中获取,如果还是获取不到就从提前暴露的包装容器中获取。如果能获取到就将其从包装容器中移除,设置到容器中。

 

原文地址:https://www.cnblogs.com/hetutu-5238/p/12394806.html