码迷,mamicode.com
首页 > 其他好文 > 详细

createBean方法详解

时间:2021-02-22 12:39:56      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:ted   fail   resolved   efi   red   singleton   ace   处理   object   

前言:

createBean是创建Bean的主要方法

createBean流程图:

技术图片

 

 createBean源码解析:

技术图片
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {

        if (logger.isTraceEnabled()) {
            logger.trace("Creating instance of bean ‘" + beanName + "‘");
        }
        RootBeanDefinition mbdToUse = mbd;//该参数是从AbstractBeanFactory的doGetBean传递过来的父子容器合并BeanDefinition

        // Make sure bean class is actually resolved at this point, and
        // clone the bean definition in case of a dynamically resolved Class
        // which cannot be stored in the shared merged bean definition.
        //判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            //克隆一份BeanDefinition,用来设置上加载出来的class对象
            //之所以后续用该副本操作,是因为不希望将解析的class绑定到缓存里的BeanDefinition
            //因为class有可能是每次都需要动态解析出来的
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // Prepare method overrides.
        //校验和准备Bean中的方法覆盖
        try {
            mbdToUse.prepareMethodOverrides();//如果是0个则抛异常,如果是1个也就没有重载的必要
        }
        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.
            //如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象
            //resolveBeforeInstantiation只是针对有自定义的targetsource,
            //因为自定义的targetsource不是spring的bena,那么肯定不需要进行后续的一系列的实例化,初始化。
            //所以可以在resolveBeforeInstantiation直接进行proxy
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                //如果这里有处理器在bean创建的之前 给出了代理bean,则无需执行后续的逻辑,
                // 直接返回用户给出的bean
                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);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean ‘" + beanName + "‘");
            }
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            // A previously detected exception with proper bean creation context already,
            // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }
createBean源码解析

 

createBean方法大致流程:

(1)判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载(如果可以,克隆一份BeanDefinition)  

  (2)用BeanDefinition副本调用prepareMethodOverrides()方法,进行校验Bean和准备Bean中的方法覆盖(处理方法覆盖

(3)?处理Bean配置的初始化前后的处理器(前置:该方法里头会调用所有的Bean处理器,如果处理器中有调换了bean的,则返回bean,如果没有则返回null)

(4)?调用doCreateBean()方法,该方法是创建Bean的入口

 

createBean方法详解

标签:ted   fail   resolved   efi   red   singleton   ace   处理   object   

原文地址:https://www.cnblogs.com/zcl1116/p/14426027.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!