做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一

经过上面几节的简单介绍我们了解了spring的一些组件,现在我们来分析一下AbstractApplicationContext中的refresh()这个核心方法吧~

用我们上一节的代码,debug进入refresh方法:

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 准备beanfactory来使用这个上下文.做一些准备工作,例如classloader,beanfactoryPostProcessor等
			prepareBeanFactory(beanFactory);

			try {
				//允许上下文的子类去执行postProcessor
				postProcessBeanFactory(beanFactory);

				// 开始执行注册到该上下文的BeanFactoryPostProcessors
				invokeBeanFactoryPostProcessors(beanFactory);

				// 开始注册BeanPostProcessor来拦截其他的bean的初始化过程
				registerBeanPostProcessors(beanFactory);

				// 初始化消息源
				initMessageSource();

				//注册上下文事件的广播集
				initApplicationEventMulticaster();

				//初始化一些特殊的bean
				onRefresh();

				//查询并校验监听器并注册
				registerListeners();

				// 实例化所有非懒加载的所有bean
				finishBeanFactoryInitialization(beanFactory);

				//最后一步发布所有的运用
				finishRefresh();
			}

			catch (BeansException ex) {
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

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

				// Propagate exception to caller.
				throw ex;
			}
		}
	}

结合上一节我们给出的spring的一些组件实例化的初始化顺序图:

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

我们先看invokeBeanFactoryPostProcessors(beanFactory)这个方法

<span style="color:#000000;">protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		// 先执行BeanDefinitionRegistryPostProcessors,因为我们这边没有实现这个接口,先暂时忽略,这段代码
		Set<String> processedBeans = new HashSet<String>();
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
			List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
					new LinkedList<BeanDefinitionRegistryPostProcessor>();
			for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryPostProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
					registryPostProcessors.add(registryPostProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}
			Map<String, BeanDefinitionRegistryPostProcessor> beanMap =
					beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.class, true, false);
			List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =
					new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());
			OrderComparator.sort(registryPostProcessorBeans);
			for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {
				postProcessor.postProcessBeanDefinitionRegistry(registry);
			}
			invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
			processedBeans.addAll(beanMap.keySet());
		}
		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);
		}

		//在beanFactory中获取实现BeanFactoryPostProcessor这个接口的bean的名称
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// 将获取到的BeanFactoryPostProcessors的bean分类,根据这些bean是否也实现了PriorityOrdered,Ordered这些接口,或者其他,因为我们的例子中
		// 并没有实现这些接口,所以我们的"springMultiBean"这个在spring-init.xml中(代码见上一节)定义的bean将进入nonOrderedPostProcessorNames.add(ppName)这个代码块
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		//首先先执行实现“权重排序”的BeanFactoryPostProcessors,我们的bean“springMultiBean”并没有实现,所以不管
		OrderComparator.sort(priorityOrderedPostProcessors);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// 然后执行实现“排序”的接口的BeanFactoryPostProcessors,我们也没有实现,暂时不看这块代码块
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		OrderComparator.sort(orderedPostProcessors);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// 最后执行“其他”的BeanFactoryPostProcessors,这边就即将执行我们的springMultiBean这个bean的BeanFactoryPostProcessors
		// 这边新建了一个List类型是BeanFactoryPostProcessor,好了,这边就开始需要实例化实现BeanFactoryPostProcessor的bean了,否则,
		// 无法放入List<BeanFactoryPostProcessor> 也就是说,如果想先执行BeanFactoryPostProcessor的方法,必须先实例化实现该接口的bean
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		//可能我们的配置文件有很多的bean实现了BeanFactoryPostProcessors,循环bean的名字
		for (String postProcessorName : nonOrderedPostProcessorNames) {
		    //底下的方法块是核心块,getBean这个方法就是初始化实现BeanFactoryPostProcessor这个接口的bean了,实例化好了之后放入List<BeanFactoryPostProcessor>
			nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		//批量执行nonOrderedPostProcessors中的BeanFactoryPostProcessor
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
	}</span>

好了,到目前为止,我们应该知道了上一节的spring Bean实例化顺序的运行截图了:

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

也就是我们的上次总结的结论:

①首先执行的是构造函数

②然后执行的BeanNameAware这个接口中的方法

③然后执行的是BeanFactoryAware这个接口中的方法

④执行InitializingBean接口中的afterPropertiesSet的方法

⑤执行我们在xml中定义的init-method这个方法

⑥最后执行的是BeanFactoryPostProcessor这个方法

分析了invokeBeanFactoryPostProcessors这个方法,我们知道这个方法就是去执行BeanFactoryPostProcessor这个接口中的方法去的,上面代码注释也清楚的写到如果想先执行BeanFactoryPostProcessor这个接口的方法,必须先去实例化实现这个接口的Bean,也就是getBean这个方法了,即在执行⑥之前,①~⑤这些方法全是在getBean这个方法中执行的:

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

我们接着分析一下getBean这个超级核心的方法:

<span style="color:#000000;">@SuppressWarnings("unchecked")
	protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		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 {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			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);
			}

			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dependsOnBean : dependsOn) {
						getBean(dependsOnBean);
						registerDependentBean(dependsOnBean, beanName);
					}
				}

				// Create bean instance.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						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 '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
							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;
	}
</span>

好吧~,这个getBean的具体实现貌似有点长,一步步分析吧

第一部分:

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》


这个方法首先先去singleton缓存中去找实例(这里我们肯定没找到,应该我们没有把我们的bean手动放入singletonObjects这个Map里面去)

第二部分:

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

这段代码是先获取该beanFactory父factory,希望从这些factory中获取,如果该beanfactory有父类,则希望用父类去实例化该bean,我们这边的beanfactory为null,暂不讨论~

接着看第三部分:

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》


上图中

第一部分先标记目前的bean的正在创建

第二部分获取根据beanName该bean在beanfactory中的beanDefinitionMap的BeanDefinition,然后去获取这个bean依赖的bean,如果依赖的bean还没有创建,则先创建依赖的bean,递归调用,(Dependence Inject依赖注入的概念吧),如果找不到依赖,则忽略

第三部分:如果是单例(我们暂时只讨论如何创建单例)

则调用createBean()这个方法

好了,我们暂不看Prototype创建的过程,我们接着跟踪createBean()

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

上图中

第①部分:确保该bean的class是真实存在的,也就是该bean是可以classload可以找到加载的

第②部分:准备方法的重写

第③部分(很重要):请注意,这边有个return,也就是说这边可以返回bean了,但看注释:Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.这边就很清晰了,我们以前在beanPostProcessor的章节讲过,beanPostProcessor是可以临时修改bean的,它的优先级高于正常实例化bean的(也就是第四部分实例化的方法),如果beanPostProcessor能返回,则直接返回了,这边代码下次分析,我们还是先分析主要流程:

看第四部分:

doCreateBean(beanName, mbd, args)这个方法

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

这个方法首先初始化一个BeanWrapper,然后再看createBeanInstance()

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》


这块代码主要是再次对bean做安全检查并确定该bean有默认的构造函数,createBeanInstance()这个方法最后一行

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

此时构造函数打印了我们system的内容,也就是第一个打印的

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》


回到doCreateBean()这个方法

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

初始化bean,的确,现在bean已经实例化了,开始初始化该bean,进入initializeBean(…)这个方法

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》



执行aware方法(看来beanFactoryAware和beanNameAware要执行了)

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

看源代码果然:

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

接着

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》


开始执行初始化方法

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

首先先判断该bean是否实现了InitializingBean,如果实现了先执行afterPropertiesSet这个方法,然后如果该bean又执行了init-method,事实的确如此:

《做一个合格的程序猿之浅析Spring IoC源码(十一)Spring refresh()方法解析之一》

好了,到此为止,我们的第一个名为“springMultiBean”已经初始化了,实例化好的大体步骤我们已经基本了解了,大家先体会一下,我们spring-init.xml中还有一个bean”springOtherBean“没讲解,下次分解~正好一起重新分析细节~


    原文作者:Spring Cloud
    原文地址: https://blog.csdn.net/linuu/article/details/50865358
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞