转载

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<Resource> 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> T doGetBean(
			final String name, final Class<T> 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;
	}

复制代码
原文  https://juejin.im/post/5db29107e51d4529ed2917cb
正文到此结束
Loading...