原创

Spring获取Bean的流程(一)

一、样例

package com.yueny.fw.practice.spring;

import com.yueny.fw.practice.lock.Deadlock;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author yueny09 <deep_blue_yang@126.com>
 * @Date 2019-10-21 14:10
 */
public class ApplicationMain {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext( "classpath:/config/spring-bean.xml");
        Deadlock deadlock = context.getBean("deadlock", Deadlock.class);
        System.out.println(deadlock.toString());
    }

}

二、ApplicationContext 类初始化流程分析

ClassPathXmlApplicationContext 加载器的时序图

见《Spring获取Bean的流程(二)》ClassPathXmlApplicationContext 加载器的时序图

1 构造器调用:

ClassPathXmlApplicationContext 的构造器中调用类同名方法:

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[] {configLocation}, true, null);
}

2.点击this跳转到初始化方法:

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
            throws BeansException {
        // super()方法是一直到父类AbstractXmlApplicationContext --> AbstractRefreshableConfigApplicationContext --> AbstractRefreshableApplicationContext --> AbstractApplicationContext 中,将ApplicationContext的环境属性设置给本类的环境属性,包括一些profile,系统属性等.
        // 执行了  getEnvironment().merge 合并操作
        super(parent);

        setConfigLocations(configLocations);    // 调用父类方法,将xml配置文件地址名字给父类的String数组属性

        if (refresh) {
            refresh(); // 进行初始化,所有的逻辑其实都在这个方法里面进行
        }
    }

3.refresh 方法

ClassPathXmlApplicationContext中的refresh方法,实际上调用的是父类org.springframework.context.support.AbstractApplicationContext的方法。

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 在刷新之前设置一些参数,比如设置开始时间戳,上下文是否激活的标志,输出刷新上下文的信息,验证一些必要的属性, 见 3.1
            // Prepare this context for refreshing.
            prepareRefresh();

            // 这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
            // 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
            // 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
            // 详情见3.2及3.2.*
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

             // 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean,详情见 3.4
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);

            // prepareBeanFactory()方法调用之后,是一个try-catch代码块,如果有BeanException异常产生则会停止refresh并且销毁已创建的资源
            try {
                // 获取容器级别的后处理器,允许上下文的子类中对beanFactory进行后处理,在应用上下文内部beanFactory初始化之后可以修改beanFactory,此时所有的BeanDefinittions都已经被加载,但未被实例化,具体的实现在AbstractRefreshableWebApplicationContext
                // 默认方法体是空的,主要是用来扩展beanfactory的,扩展点是在bean等配置都已经加载但还没有进行实例化的时候。
                // 到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
                postProcessBeanFactory(beanFactory);

                // 详情见 3.5
                // 调用BeanFactoryPostProcessor和BeanDefintionRegistoryPostProcessor这两个后置处理器
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // 详情见 3.5
                // 注册BeanPostProcessor 后置处理器,用来拦截bean的创建,详情见 xxx
                // 注意,到这里 Bean 还没初始化
                registerBeanPostProcessors(beanFactory);

                // 详情见 3.6
                // 初始化消息源
                // Initialize message source for this context.
                initMessageSource();

                // 初始化应用程序事件广播器,用户可以自定义一个事件广播器,如果用户没有定义,那么使用默认的事件广播器SimpleApplicationEventMulticaster
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // 空方法由子类扩展,可以在实例化bean之前做一些ApplicationContext相关的操作
                // Initialize other special beans in specific context subclasses.
                onRefresh();

                // 注册和检测事件监听器
                // Check for listener beans and register them.
                registerListeners();

                //单例模式的bean实例化,初始化(non-lazy-init),即所有单例非懒加载Bean的调用点
                // 重点,重点,重点
                // 初始化所有的 singleton beans (lazy-init 的除外)
                // 详见 3.7
                finishBeanFactoryInitialization(beanFactory);

                // applicationContext刷新完成后的处理,例如生命周期监听器的回调,广播通知等
                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }
  • 3.1:环境属性的一些初始化

    prepareRefresh();

  • 3.2 点进去 obtainFreshBeanFactory() 方法

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
      // 执行的为 ClassPathXmlApplicationContext 的父类方法 AbstractRefreshableApplicationContext
      //实际刷新上下文的方法,这个方法就是实际的刷新上下文方法,其中会调用loadBeanDefinitions(beanFactory)加载配置文件中的内容到BeanDefiniton中。 详见下述代码段
      refreshBeanFactory();
    
      ConfigurableListableBeanFactory beanFactory = getBeanFactory();
      if (logger.isDebugEnabled()) {
          logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
      }
      return beanFactory;
    }
    

    refreshBeanFactory(): org.springframework.context.support.AbstractRefreshableApplicationContext中的方法

    protected final void refreshBeanFactory() throws BeansException {
      // 如果BeanFactory存在就销毁关闭,在后续逻辑中重新创建
      if (hasBeanFactory()) {
          destroyBeans();
          // 将BeanFactory设置为null,序列化id设置为null
          closeBeanFactory();
      }
    
      try {
          /**
          * 创建DefaultListableBeanFactory,
          * 此类是整个Bean加载的核心部分,是Spring注册加载Bean的默认实现,是整个Spring IOC的始祖.
          * 对beanFactory进行设置,bean注册等操作,最后将beanFactory赋值给本类的beanFactory属性
          */
          /* 我们看《BeanFactory 接口相关的继承结构》图可以看出,ConfigurableListableBeanFactory 只有一个实现类 DefaultListableBeanFactory,而且实现类 DefaultListableBeanFactory 还通过实现右边的 AbstractAutowireCapableBeanFactory 通吃了右路。
          */
          DefaultListableBeanFactory beanFactory = createBeanFactory();
    
          beanFactory.setSerializationId(getId());
    
          // 由AbstractRefreshableApplicationContext实现,
          // 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
          customizeBeanFactory(beanFactory);
    
          // 加载 Bean 到 BeanFactory 中, 即Bean的注册, 此处实现类为 AbstractXmlApplicationContext,详情见 3.2.1
          loadBeanDefinitions(beanFactory);
    
          synchronized (this.beanFactoryMonitor) {
              this.beanFactory = beanFactory;
          }
      }
      catch (IOException ex) {
          throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
      }
    }
    

3.2.1 AbstractXmlApplicationContext 类中的 loadBeanDefinitions(beanFactory);
```
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//创建要给beanDefinitionReader,用于读取BeanDefinition
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

// Configure the bean definition reader with this context's
// resource loading environment.
// 然后设置环境属性以及 资源加载器ResourceLoader 为this(实际为 ClassPathXmlApplicationContext)
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

// 接着初始化读取器 initBeanDefinitionReader,其实这个是提供给子类覆写的
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);

// 加载BeanDefiniton,主要的功能从配置文件中读取BeanDefiniton注册到注册表中。详见 3.2.2
loadBeanDefinitions(beanDefinitionReader);

}


> 3.2.2 AbstractXmlApplicationContext 类中的 loadBeanDefinitions(beanDefinitionReader)

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources(); // 加载资源
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations(); // 加载之前设置的xml配置文件资源
if (configLocations != null) {
// 循环加载xml文件的Bean返回Bean总个数,详见 3.2.3
reader.loadBeanDefinitions(configLocations);
}
}


> 3.2.3 XmlBeanDefinitionReader 类中的 loadBeanDefinitions

public int loadBeanDefinitions(String location, Set actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
}

if (resourceLoader instanceof ResourcePatternResolver) {
    // Resource pattern matching available.
    try {
        // 获取加载器中的Resource[] 数组
        Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
        //  查看loadBeanDefinitions,循环加载所有的资源,返回总数资源中的Bean
        int loadCount = loadBeanDefinitions(resources);
        if (actualResources != null) {
            for (Resource resource : resources) {
                actualResources.add(resource);
            }
        }
        if (logger.isDebugEnabled()) {
            logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
        }
        return loadCount;
    }
    catch (IOException ex) {
        throw new BeanDefinitionStoreException(
                "Could not resolve bean definition resource pattern [" + location + "]", ex);
    }
}
else {
    // Can only load single resources by absolute URL.
    Resource resource = resourceLoader.getResource(location);

    // 详见 3.2.4
    int loadCount = loadBeanDefinitions(resource);
    if (actualResources != null) {
        actualResources.add(resource);
    }
    if (logger.isDebugEnabled()) {
        logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
    }
    return loadCount;
}

}


> 3.2.4 loadBeanDefinitions讲解

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}

    //  resourcesCurrentlyBeingLoaded 定义为 new NamedThreadLocal<Set<EncodedResource>>,
    // 这里对正在解析的xml资源放入ThreadLocal中,保证只有本次线程可以访问,加载完之后再移除. 保证并发和同步
    Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
    if (currentResources == null) {
        currentResources = new HashSet<EncodedResource>(4);
        this.resourcesCurrentlyBeingLoaded.set(currentResources);
    }

    // 先添加进 threadLocal, 加载完成之后 finally 中再移除 threadLocal
    if (!currentResources.add(encodedResource)) {
        throw new BeanDefinitionStoreException(
                "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
    }

    try {
        InputStream inputStream = encodedResource.getResource().getInputStream();
        try {
            InputSource inputSource = new InputSource(inputStream);
            if (encodedResource.getEncoding() != null) {
                inputSource.setEncoding(encodedResource.getEncoding());
            }

            // 此处 解析 Document, 并在解析之后进行注册(bean的注册方法 registerBeanDefinitions(Document doc, Resource resource),详见 详见 3.3)
            return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
        }
        finally {
            inputStream.close();
        }
    }
    catch (IOException ex) {
        throw new BeanDefinitionStoreException(
                "IOException parsing XML document from " + encodedResource.getResource(), ex);
    }
    finally {
        currentResources.remove(encodedResource);
        if (currentResources.isEmpty()) {
            this.resourcesCurrentlyBeingLoaded.remove();
        }
    }
}

* 3.3 bean的注册方法 
XmlBeanDefinitionReader中调用的 bean的注册方法 registerBeanDefinitions(Document doc, Resource resource), 并没有执行真正的注册,而是把工作委托给了BeanDefinitionDocumentReader对象去处理。

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}

实际上所谓的注册,就是把beanName和beanDefinition对象作为键值对放到BeanFactory对象的beanDefinitionMap。

* 3.4 prepareBeanFactory(beanFactory)
> prepareBeanFactory :准备BeanFactory,设置一些参数,比如后置处理器,

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// //设置类加载器
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());

//设置表达式解析器,用来解析BeanDefiniton中的带有表达式的值,spring3增加了表达式语言的支持,默认可以使用#{bean.xxx}的形式来调用相关属性值。
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 增加了一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

// 配置后置处理器,主要的作用就是在spring实例化bean的前后做一些操作。

// 添加了一个处理aware相关接口的beanPostProcessor扩展,实现了 Aware 接口的 beans 在初始化的时候,这个 processor 负责回调,
// 主要是使用beanPostProcessor的postProcessBeforeInitialization()前置处理方法实现aware相关接口的功能,
// aware接口是用来给bean注入一些资源的接口,
// 回调 ApplicationContextAware、EnvironmentAware、ResourceLoaderAware。
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

//忽略自动装配的类,这些类都不能使用@Resource或者@Autowired自动装配获取对象
// 如果某个 bean 依赖于以下几个接口的实现类,在自动装配的时候忽略它们,  Spring 会通过其他方式来处理这些依赖。
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

//注册可解析的自动装配类的特殊规则,如果是BeanFactory类型,则注入beanFactory对象,如果是ResourceLoader、ApplicationEventPublisher、ApplicationContext类型则注入当前对象(applicationContext对象)。
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

// 这里涉及到特殊的 bean,名为:loadTimeWeaver。

// 如果定义了则添加loadTimeWeaver功能的beanPostProcessor扩展,并且创建一个临时的classLoader来让其处理真正的bean。
// spring的loadTimeWeaver主要是通过 instrumentation 的动态字节码增强在装载期注入依赖。
// tips: ltw 是 AspectJ 的概念,指的是在运行期进行织入,这个和 Spring AOP 不一样,
// 感兴趣的读者请参考关于 AspectJ 的另一篇文章 https://www.javadoop.com/post/aspectj
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}

// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
    beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}

/**
* 这部分首先判断是否定义了名为systemProperties的bean,如果没有则加载系统获取当前系统属性System.getProperties()并注册为一个单例bean。假如有AccessControlException权限异常则创建一个ReadOnlySystemAttributesMap对象,可以看到创建时重写了getSystemAttribute()方法,查看ReadOnlySystemAttributesMap的代码可以得知在调用get方法的时候会去调用这个方法来获取key对应的对象,当获取依旧有权限异常AccessControlException的时候则返回null。
*/
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
    beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
// 同上,此处是获得 系统环境变量
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
    beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}

}


* 3.5 invokeBeanFactoryPostProcessors(beanFactory),这个方法从名字就可以看出是在调用BeanFactoryProcessor
> 在装配完成配置后执行这些后处理器,这里涉及到一些接口。
我们在开发时可以实现这些接口扩展功能,例如:InstantiationAwareBeanPostProcessor包含两个方法。一个是在实例化前调用,一个在实例化后,初始化前调用,可以用来做特殊作用,例如代理等等
DestructionAwareBeanPostProcessor在销毁前调用

* 3.6 initMessageSource()
> MessageSource/事件监听器,初始化国际化信息资源


* 3.7 finishBeanFactoryInitialization(beanFactory)


## 三、getBean 流程分析
* 入口:ApplicationMain 类的 ApplicationContext.getBean
* AbstractApplicationContext.getBean
* AbstractBeanFactory类下面的doGetBean()方法
> abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory 类

protected T doGetBean(
final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {

    /*
    1、转换beanName(别名转换) 
    平时开发中传入的参数name可能只是别名,也可能是FactoryBean,所以需要进行解析转换:
    (1)消除修饰符,比如name="&test",会去除&使name="test";
    (2)解决spring中alias标签的别名问题
    */ 
    final String beanName = transformedBeanName(name);
    Object bean;

    //2、尝试从缓存(DefaultSingletonBeanRegistry$singletonFactories)中加载实例,如果获取不到就从singletonFactories中加载
    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    //如果缓存中存在对应的bean
    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 + "'");
            }
        }

        //3、缓存渠道的bean的实例化。从缓存中获取的bean是原始状态的bean,需要在这里对bean进行bean实例化。
        // 此时会进行 合并RootBeanDefinition、BeanPostProcessor进行实例前置处理、实例化、实例后置处理。
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }

    else { // 如果缓存中没有对应bean

        //4、循环依赖检查。 (构造器的循环依赖)循环依赖存在,则报错。
        // @see  https://blog.csdn.net/qq_36381855/article/details/79752689
        // Fail if we're already creating this bean instance:
        // We're assumably within a circular reference.
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 5、如果缓存中没有数据,就会转到父类工厂去加载
        //获取父工厂
        // Check if bean definition exists in this factory.
        BeanFactory parentBeanFactory = getParentBeanFactory();

        /*
            !containsBeanDefinition(beanName)就是检测如果当前加载的xml配置文件中不包含beanName所对应的
            配置,就只能到parentBeanFacotory去尝试加载bean。
        */
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            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);
            }
        }

        if (!typeCheckOnly) {
            markBeanAsCreated(beanName);
        }

        //6、存储XML配置文件的GernericBeanDefinition转换成RootBeanDefinition,即为合并父类定义。
        /*
            XML配置文件中读取到的bean信息是存储在GernericBeanDefinition中的,但Bean的后续处理是针
            对于RootBeanDefinition的,所以需要转换后才能进行后续操作。
        */
        try {
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // Guarantee initialization of beans that the current bean depends on.
            //7、初始化依赖的bean
            String[] dependsOn = mbd.getDependsOn();
            //bean中可能依赖了其他bean属性,在初始化bean之前会先初始化这个bean所依赖的bean属性。
            if (dependsOn != null) {
                for (String dependsOnBean : dependsOn) {
                    if (isDependent(beanName, dependsOnBean)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
                    }
                    registerDependentBean(dependsOnBean, beanName);
                    getBean(dependsOnBean);
                }
            }

            //8、创建bean
            // Create bean instance.
            if (mbd.isSingleton()) {
                sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                    @Override
                    public Object getObject() throws BeansException {
                        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);
            }

            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, new ObjectFactory<Object>() {
                        @Override
                        public Object getObject() throws BeansException {
                            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;
        }
    }

    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
        try {
            return getTypeConverter().convertIfNecessary(bean, requiredType);
        }
        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;
}

```

正文到此结束
广告是为了更好的提供数据服务
本文目录