Spring源码之AbstractApplicationContext解析(refresh)


Spring源码之AbstractApplicationContext解析


阅读前提须知

1、此源码是在我公司的随便一个Spring boot项目中查看的,具体方法就是双击shift,搜索AbstractApplicationContext文件,然后在文件中找到refresh()方法进行阅读(进入该文件后会提示
download source,下载源码)
2、此项目是基于Spring 2.5.4.Release版本
3、文中所有Java代码都是源码
4、最好边看边点进去看,光是看文章,没人读得下去,读下去了也理解不了

项目启动过程中,AbstractApplicationContext做了非常多重要的工作,由于这个类使用了模板方法的设计模式,所以阅读起来也非常方便。所有的步骤,无论是由子类实现,还是由当前类实现,都是在模板方法中顺序调用的。而这个模板方法就是refresh()

Spring boot哪里调用了

Spring boot项目都有启动类,入口就是启动类中的main方法,如下:
Spring源码之AbstractApplicationContext解析(refresh)_第1张图片
run方法点进去,经过几层包装后,进入实际实现的方法如下,关键就是下面的refreshContext方法
Spring源码之AbstractApplicationContext解析(refresh)_第2张图片
此run方法的核心方法就是refreshContext方法,而refreshContext方法的核心也就是在AbstractApplicationContext中的refresh()方法中

总览

我们把视角给到refresh()方法:

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      //准备刷新上下文环境
      prepareRefresh();

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

      // Prepare the bean factory for use in this context.
      //对BeanFactory进行各种功能填充
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         //子类覆盖方法做额外的处理
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         //注册,实例化,调用各种BeanFactory处理器
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         //注册 "拦截Bean创建" 的Bean处理器,这里只是注册,真正调用是再拿去Bean的时候
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         //为上下文初始化Message源,即不同语言的消息体,国际化处理
         initMessageSource();

         // Initialize event multicaster for this context.
         //初始化应用消息广播器,并放到applicationEventMulticaster bean中
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         //留给子类来初始化其他bean
         onRefresh();

         // Check for listener beans and register them.
         //在所有注册的bean中查找Listener bean,注册到消息广播中
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         //实例化、初始化剩下的单实例(非惰性)
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         //完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
         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();
      }
   }
}

别看这方法挺长,其实内部实现比你想到的还复杂。这个方法到底做了些什么,我们来一步步解析这个方法。额,如果你不看源码,那我就把总结放在这里:

⑴.准备刷新上下文环境
⑵.初始化BeanFactory
⑶.对BeanFactory进行各种功能填充
⑷.子类覆盖方法做额外的处理
⑸.注册,实例化,调用各种BeanFactory处理器
⑹.注册拦截Bean创建的Bean处理,这里只是注册,真正调用是再拿去Bean的时候
⑺.为上下文初始化Message源,即不同语言的消息体,国际化处理
⑻.初始化应用消息广播器,并放到applicationEventMulticaster bean中
⑼.留给子类来初始化其他bean
⑽.在所有注册的bean中查找Listener bean,注册到消息广播中
⑾.初始化剩下的单实例(非惰性)
⑿.完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人

好的,如果只是准备初步了解一下refresh的刷新流程,看完上文就够了,总结的非常到位了,如果还想继续研究,那还得耐心往下看

1、startupShutdownMonitor

517 synchronized (this.startupShutdownMonitor)

首先映入眼帘的就是这么一个synchronized关键字,这个关键字主要是用于保证同一时间,只能有一个线程持有startupShutdownMonitor对象的锁,而这个对象就是在AbstractApplicationContext中随便定义的一个对象:

  /** Synchronization monitor for the "refresh" and "destroy". */
192 private final Object startupShutdownMonitor = new Object();

根据注解也可以知道这是用于refresh方法和destroy方法的同步监视器。

2、prepareRefresh()

// Prepare this context for refreshing.
519 prepareRefresh();

模板方法refresh()中的第一个方法,作用是在执行刷新前做一些准备,包括:

1、设置启动时间:startupDate
2、设置启动和关闭的标识符,标识状态为启动
3、初始化属性资源,一般是servlet资源
4、获取环境对象Environment,并验证所需的属性文件是否都已经放到了Environment中
5、初始化监听器

具体实现也贴出来:

protected void prepareRefresh() {
		// Switch to active.
		// 设置容器启动的时间
		this.startupDate = System.currentTimeMillis();
		// 容器的关闭标志位
		this.closed.set(false);
		// 容器的激活标志位
		this.active.set(true);

		// 记录日志
		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		// 留给子类覆盖,初始化属性资源
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		// 创建并获取环境对象,验证需要的属性文件是否都已经放入环境中
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		// 判断刷新前的应用程序监听器集合是否为空,如果为空,则将监听器添加到此集合中
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// Reset local application listeners to pre-refresh state.
			// 如果不等于空,则清空集合元素对象
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// Allow for the collection of early ApplicationEvents,
		// to be published once the multicaster is available...
		// 创建刷新前的监听事件集合
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

3、obtainFreshBeanFactory()

此方法的内部为:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   return getBeanFactory();
}

这个方法在我这里是有歧义的,我们来看上述代码中的refreshBeanFactory()方法,会发现这是个抽象方法,没有具体实现。但是在两个子类中实现了具体逻辑:
请添加图片描述

这里就是产生歧义的地方了,到底调用的是哪个实现,是AbstractRefreshableApplicationContext,还是GenericApplicationContext?

我在众多博客中,看到的都是走的是AbstractRefreshableApplicationContext,然后对AbstractRefreshableApplicationContext方法一顿分析。
例如:
https://www.cnblogs.com/xuelin1221/p/10051938.html

AbstractRefreshableApplicationContext中的refreshBeanFactory()方法的具体实现如下:

@Override
protected final void refreshBeanFactory() throws BeansException {
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      customizeBeanFactory(beanFactory);
      loadBeanDefinitions(beanFactory);
      synchronized (this.beanFactoryMonitor) {
         this.beanFactory = beanFactory;
      }
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

做的事情可以概括为:
如果beanFactory对象已存在,销毁它,并重新创建一个beanFactory,然后为这个新的BeanFactory赋予一些属性。当然最重要的就是将BeanDefinitions加载到BeanFactory中,加载bean定义的过程也挺复杂的,这里不细讲。我们主要是记住,在refresh()中调用的obtainFreshBeanFactory()方法中进行了加载beanDefinitions的过程。

但是我在项目启动时进行debug,refreshBeanFactory()方法实际走的是GenericApplicationContext中的具体实现,这个实现只做了一件事,那就是给BeanFactory加了个序列化id,如下:

@Override
protected final void refreshBeanFactory() throws IllegalStateException {
   if (!this.refreshed.compareAndSet(false, true)) {
      throw new IllegalStateException(
            "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
   }
   this.beanFactory.setSerializationId(getId());
}

我启动了n遍项目,都是走的这个实现。

对于这个疑问,我请教了同事,但是最终也没讨论出定论:
其一:同事坚称,AbstractRefreshableApplicationContext是一个抽象类,对抽象类中的方法进行调用,肯定只会调用其非抽象类子类中的实现,也就是说此抽象类中的方法不可能被调用,这就是冗余代码。存疑。
其二:抽象类中的实现也可以被调用,在ApplicationContext的某些子类中,会调用这个方法,只是我们是在实际项目中调用,可能影响到了Spring启动的流程。

两者观点冲突,我更倾向于第二种,待有识之士解答。

总之,无论是走哪一个实现,自从执行完此方法后,beanFactory就已经绝对存在了,之前如果说是可能存在,可能不存在,但是到了这一步,beanFactory就是必然存在。

这里补充下,Spring容器究竟是什么?

Spring中的容器,也就是一个bean工厂,如BeanFactory
而org.springframework.context.ApplicationContext作为BeanFactory的子接口,主要便是用于完成容器的配置,初始化,管理bean。一个Spring容器就是某个实现了ApplicationContext接口的类的实例。也就是说,从代码层面,Spring容器其实就是一个ApplicationContext。

在普通的JAVA工程中,我们可以通过代码显式new一个ClassPathXmlApplicationContext或者FileSystemXmlApplicationContext来初始化一个Spring容器。


4、prepareBeanFactory(beanFactory)

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   	// 设置beanFactory的classLoader为当前context的classLoader
	beanFactory.setBeanClassLoader(getClassLoader());
    //设置beanFactory的表达式语言处理器,spring 3增加了表达式语言的支持
    //默认可以使用#{bean.xxx}的形式来调用相关的属性
	beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
    //为beanFactory增加一个系统默认的属性编辑器,这个编辑器可以设置bean的普通属性的值,但是
	//如Date这种类型就没办法设置,需要自定义属性编辑器才行
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, 	this.getEnvironment()));
    // 添加BeanPostProcessor
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    //设置了几个忽略自动装配的接口,  beanfactory.ignoreDependencyInterface(ResourceLoaderAware.class)的 
    //作用就是 beanFactory的子类初始化的时候,Spring会忽略ResourceLoaderAware,不会主动注入此依赖
	beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
	beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
	beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

	// BeanFactory interface not registered as resolvable type in a plain factory.
	// MessageSource registered (and found for autowiring) as a bean.
       //这个registerResolvableDependency方法是Spring为了避免由于某接口有多个实现类,从而
       //导致Spring注入某接口时,不知道该注入哪个实现类,从而报错。作用就是指定实现类的具体类型
	beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
	beanFactory.registerResolvableDependency(ResourceLoader.class, this);
	beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
	beanFactory.registerResolvableDependency(ApplicationContext.class, this);

	// Register early post-processor for detecting inner beans as ApplicationListeners.
	//翻译一下就是:将用于检测内部 bean 的早期后处理器注册为 ApplicationListener
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

	// Register default environment beans.
    //添加默认的系统环境bean
	if (!beanFactory.containsBean(ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
	}

	if (!beanFactory.containsBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
	}

	if (!beanFactory.containsBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
	}
}

顾名思义,作用就是准备bean工厂,以在此上下文中使用,总结一下这个方法的作用就是:
1、为beanFactory对象装载(或者说初始化)类加载器、表达式语言处理器、属性编辑器、bean后置处理器。
2、设置beanFactory在自动注入的时候,需要忽略的几个依赖,方便框架使用者对bean进行自定义。
3、指定几个主要接口的实现类的具体类型。
4、添加默认的系统环境bean,也就是Environment。

名称解释:

类加载器:顾名思义,用于加载所有类文件的类
表达式语言处理器:也就是SpEL处理器,SpEL类似于jsp中的EL表达式,是一个可以处理一些使用SpEL写的代码的类
属性编辑器:任何实现 java.beans.PropertyEditor 接口的类都是属性编辑器。属性编辑器的主要功能就是将外部的设置值转换为 JVM 内部的对应类型,所以属性编辑器其实就是一个类型转换器。
bean后置处理器:也就是BeanPostProcessor,熟悉不?面试时如果你说你读了Spring的源码,90%会问到这个东西,这个东西非常非常重要,这只是第一次接触,稍微了解一下就好。作用是可以在bean初始化之前和之后做增强处理 ,最典型的AOP案例。问到Spring 中Bean的生命周期的时候,这个不得不提。

5、postProcessBeanFactory(beanFactory)

// Allows post-processing of the bean factory in context subclasses.
//允许在上下文子类中对 bean 工厂进行后处理。
postProcessBeanFactory(beanFactory);

此方法在AbstractApplicationContext中是个空壳方法(钩子方法),具体实现会由子类实现。ps(我们一般如果要在bean实例化前后进行自定义,可以通过实现BeanFactoryPostProcess接口,并实现其postProcessBeanFactory方法进行自定义,与这里的postProcessBeanFactory方法没什么关系,别搞混了)我们可以看到有许多的实现:
Spring源码之AbstractApplicationContext解析(refresh)_第3张图片
我在每个实现上都加了断点进行debug,然后启动项目,发现走的是图中的AnnotationConfigServletWebServerApplicationContext中的实现,如下:

@Override
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		super.postProcessBeanFactory(beanFactory);
		if (this.basePackages != null && this.basePackages.length > 0) {
			this.scanner.scan(this.basePackages);
		}
		if (!this.annotatedClasses.isEmpty()) {
			this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
		}
	}

如图,调用了super.postProcessBeanFactory(beanFactory);也就是说会先去执行父类中此方法的实现。
后续代码,通俗来讲就是在指定的基础包中扫码,返回注册的bean定义,并注册注解类。而父类此方法实现如下:注册 ServletContextAwareProcessor

/**
	 * Register ServletContextAwareProcessor.
	 * @see ServletContextAwareProcessor
	 */
	@Override
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(ServletContextAware.class);
		registerWebApplicationScopes();
	}

6、invokeBeanFactoryPostProcessors(beanFactory)

	// Invoke factory processors registered as beans in the context.
	//调用在上下文中注册为 bean 的工厂处理器。
	invokeBeanFactoryPostProcessors(beanFactory);

这小小的一个方法,也挺复杂的,我们进入内部查看:

/**
 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
 * respecting explicit order if given.
 * 

Must be called before singleton instantiation. */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }

可以看到这一步实现看起来不多,基本就两个步骤,但是第一行代码就是非常的复杂的,复杂到我都要看不下去了,内部实现有上百行代码,烦死个人。
1.getBeanFactoryPostProcessors():
拿到当前应用上下文beanFactoryPostProcessors变量中的值
getBeanFactoryPostProcessors() 会拿到当前应用上下文中已经注册的 BeanFactoryPostProcessor(可以看到方法是在AbstractApplicationContext中,当前应用上下文就是它),在默认情况下,this.beanFactoryPostProcessors 是返回空的。 非默认情况下就是我们自己去实现ApplicationContextInitializer接口,然后在initialize 方法中将自定义的beanFactoryPostProcessor加入到beanFactoryPostProcessors中

2.invokeBeanFactoryPostProcessors:
实例化并调用所有已注册的BeanFactoryPostProcessor
这行代码的作用就是:实例化并调用所有已注册的BeanFactoryPostProcessor。我们点进去查看具体实现,长代码警告!!!

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the bean factory post-processors apply to them!
			// Separate between BeanDefinitionRegistryPostProcessors that implement
			// PriorityOrdered, Ordered, and the rest.
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				sortPostProcessors(currentRegistryProcessors, beanFactory);
				registryProcessors.addAll(currentRegistryProcessors);
				invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
				currentRegistryProcessors.clear();
			}

			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// Clear cached merged bean definitions since the post-processors might have
		// modified the original metadata, e.g. replacing placeholders in values...
		beanFactory.clearMetadataCache();
	}

整个 invokeBeanFactoryPostProcessors 方法围绕两个接口,BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor,其中 BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor 。BeanDefinitionRegistryPostProcessor 主要用来在常规 BeanFactoryPostProcessor 检测开始之前注册其他 Bean 定义,说的简单点,就是 BeanDefinitionRegistryPostProcessor 具有更高的优先级,让其执行顺序在 BeanFactoryPostProcessor 之前

所以别看代码那么多,其实就是对传入的beanFactoryPostProcessors:后置bean处理器列表中的数据,进行各种划分,划分为不同BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor两种。
然后BeanDefinitionRegistryPostProcessor优先执行。

7、registerBeanPostProcessors(beanFactory)

// Register bean processors that intercept bean creation.
   registerBeanPostProcessors(beanFactory);

此方法的作用就是:实例化和注册 beanFactory 中实现了 BeanPostProcessor 接口的 Bean

又是长代码警告!!!

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

有了上一个方法:invokeBeanFactoryPostProcessors(beanFactory) 的经验后,这个方法读起来就简单多了,可以一目十行的大概理解意思:获取传入的beanFactory参数中的所有的,类型与BeanPostProcessor匹配的 bean(这句话应该不难理解吧) 。然后通过对这些bean进行分类,分为了三类,分别为实现了PriorityOrdered接口的bean、实现了Order接口的bean、没有实现如上接口的bean。然后对这些bean进行按顺序注册

注册顺序为:实现了PriorityOrdered接口的bean----->实现了Order接口并且不是MergedBeanDefinitionPostProcessor类型的bean----->没有实现如上接口并且不是MergedBeanDefinitionPostProcessor类型的bean----->类型为MergedBeanDefinitionPostProcessor的bean


8、initMessageSource()

	// Initialize message source for this context.
	//为此上下文初始化消息源
	initMessageSource();

这大概是refresh()里最简单的一个方法了?内容特别简单,作用就是:
如果BeanFactory实例中存在消息源,就为此消息源设置父消息源。如果BeanFactory实例中还没有消息源这个bean,就直接创建一个消息源,并设置父消息源。

代码如下:

这个消息源是干嘛用的?用于支持国际化的。 什么叫支持国际化?就是可以通过读取客户端的默认语言,语言为中文就自动切换为中文页面,英文就自动切换为英文。当然前提是前端后端都做了对应的国际化支持,没那么简单就是了。

如下为具体实现:

/**
	 * Initialize the MessageSource.
	 * Use parent's if none defined in this context.
	 */
	protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
			// Use empty MessageSource to be able to accept getMessage calls.
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
			}
		}
	}

补充一下,还记得不,AbstractApplicationContext是ApplicationContext的子接口,而ApplicationContext是继承了六大接口:

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver

这六大接口中,就有MessageSource,正是因为父接口继承了MessageSource,所以AbstractApplicationContext及其子类相比较于简单的BeanFactory,增加了对国际化的支持。

谈到这里,再补充一下,如果面试官问你,ApplicationContext和BeanFactory的区别是什么?
1、ApplicationContext和BeanFactory都是Spring IOC的核心接口,其中ApplicationContext是BeanFactory的子接口。
2、ApplicationContext相比较于BeanFactory,它除了拥有BeanFactory的所有功能外,还增加了许多其他功能。
①由于继承了MessageSource,所以增加了国际化的支持。
②由于继承了ResoucePatternResolver,所以增加了解析资源文件的功能。
③由于继承了ApplicationEventPublisher,所以增加了事件发布的功能。
④由于继承了EnvironmentCapable,所以具备了获取Environment的能力(ps:带有Capable后缀的接口在Spring中带有getXxx的含义,也就是实现了这个接口,就可以通过该接口的实例获取到Xxx)。
⑤由于继承了ListableBeanFactory,所以具备了直接预加载所有的bean定义的功能,而如果使用BeanFactory,客户端只能通过名称一个一个的查询得出所有的实例。
⑥由于同时继承了HierarchicalBeanFactory,所以ApplicationContext这个bean工厂具备了工厂分层的功能,也就是可以设置父工厂了。
3、ApplicationContext是在项目启动时直接初始化了所有的bean(补充一下,Bean的生命周期顺序为实例化,设置属性(依赖注入),初始化(参数的值,如果重写了用户实现了initMethod()方法的话)),而BeanFactory则是使用懒加载,在业务中实际从容器获取时,才会初始化获取的bean。所以ApplicationContext也可以在项目启动中就暴露可能出现的问题,BeanFactory需要实际用到时才会暴露。ApplicationContext也可以使用懒加载的方式初始化bean,通过在配置文件中配置:


9、initApplicationEventMulticaster()

    // Initialize event multicaster for this context.
    initApplicationEventMulticaster();

跟上一个方法一模一样的的逻辑,都是如果BeanFactory实例中存在ApplicationEventMulticaster实例,就将此实例赋值给当前上下文(ApplicationContext)的applicationEventMulticaster参数。如果不存在,就重新创建一个ApplicationEventMulticaster实例并作为单例bean注册到BeanFactory中。
源码如下:

/**
	 * Initialize the ApplicationEventMulticaster.
	 * Uses SimpleApplicationEventMulticaster if none defined in the context.
	 * @see org.springframework.context.event.SimpleApplicationEventMulticaster
	 */
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
						"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
			}
		}
	}

源码中new出来的SimpleApplicationEventMulticaster是一个事件发布器(注意,这里只是注册bean,并没有实际发布事件)。事件听起来比较难以理解。

首先,Event在实际生产中用的不算多,主要应用也差不多就是在使用观察者设计模式的时候,会和event搭个边。和MQ中的发布订阅模式也有点像。

在Spring boot中使用事件,可以参考我的另一篇博客。


10、onfresh()

// Initialize other special beans in specific context subclasses.
//初始化特定上下文子类中的其他特殊 bean。
	onRefresh();

这个方法在AbstractApplicationContext中并没有去实现,留给子类实现了。因为这个方法的作用就是提供给子类(也是上下文)进行初始化特殊的bean的

共有5个子类实现了此方法,可以分为两种:
比如在子类AbstractRefreshableWebApplicationContext、GenericWebApplicationContext、StaticWebApplicationContext中,就只是初始化了个themeSource的实例。

/**
	 * Initialize the theme capability.
	 */
	@Override
	protected void onRefresh() {
		this.themeSource = UiApplicationContextUtils.initThemeSource(this);
	}

而在ReactiveWebServerApplicationContext、ServletWebServerApplicationContext中,还做了其他操作。

@Override
	protected void onRefresh() {
		super.onRefresh();
		try {
			createWebServer();
		}
		catch (Throwable ex) {
			throw new ApplicationContextException("Unable to start web server", ex);
		}
	}

11、registerListeners()

/**
	 * Add beans that implement ApplicationListener as listeners.
	 * Doesn't affect other listeners, which can be added without being beans.
	 */
	 推送事件到响应的监听器
	protected void registerListeners() {
		// Register statically specified listeners first.
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				//使用事件广播器广播事件到对应的监听器
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

此方法的作用就是:在所有注册的bean中查找Listener bean,注册到消息广播中
在上面我们刚看完事件相关的代码,注册了一个事件发布器,而这里,就是利用这个发布器,将事件发布到对应的监听器。我们具体看看代码中的multicastEvent方法是干了什么事:

@Override
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
	ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
	Executor executor = getTaskExecutor();
	for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
		if (executor != null) {
			executor.execute(() -> invokeListener(listener, event));
		}
		else {
			invokeListener(listener, event);
		}
	}
}

代码中的关键就是invokeListener(listener,event)。listener参数就是通过getApplicationListenners方法获取的,通过debug发现,在启动阶段,有如下四个监听器:
Spring源码之AbstractApplicationContext解析(refresh)_第4张图片
这四个监听器的作用可自行百度。
invokeListener方法的作用就是:将给定的应用程序事件多播到适当的侦听器。最后会发现是调用了onApplicationEvent方法。


12、finishBeanFactoryInitialization(beanFactory)

这个方法的作用是:实例化剩下的所有非懒加载的单例(部分bean可能会通过配置文件配置为懒加载,在实际业务中从容器中获取时才会实例化,项目启动时不会实例化)

这方法就关键了,bean的生命周期里的实例化、设置属性、初始化都是在这一步完成的,可以说是非常复杂了。一步一步来吧,看源码。
以下源码

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		//为此上下文转换服务,这里有个看似很迷的操作,从BeanFactory中获取bean,然后再将bean填入BeanFactory,其实是因为获取bean有可能是从父容器获取的,所以有此一步
		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));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		//如果之前没有注册过任何 bean 后处理器 (例如 PropertyPlaceholderConfigurer bean),则注册一个默认的嵌入值解析器:  此时,主要用于解析注释属性值。
		//启动的时候是有的,所以不会走这一步
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		//尽早初始化 LoadTimeWeaverAware bean,以便尽早注册它们的转换器。
		//启动时,这一步也不会走,无视
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		//停止使用临时 ClassLoader 进行类型匹配。
		//记得吗?在前面refresh的prepareBeanFactory方法中,设置的临时ClassLoader
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		//允许缓存所有 bean 定义元数据,而不是期望进一步的更改
		//标识bean定义为最终形态,不能够再更改,为实例化、初始化做准备
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		//最关键的方法,实例化所有非懒加载的剩余所有单例
		beanFactory.preInstantiateSingletons();
	}

通过源码中我的注解,可以看到最后一行中的beanFactory.preInstantiateSingletons()才是关键代码,我们继续点进去查看:

public void preInstantiateSingletons() throws BeansException {
	if (this.logger.isInfoEnabled()) {
		this.logger.info("Pre-instantiating singletons in " + this);
	}

	List<String> beanNames;
	synchronized (this.beanDefinitionMap) {
		// 获取容器内加载的所有BeanDefinition
		beanNames = new ArrayList<String>(this.beanDefinitionNames);
	}

	// 遍历初始化所有非懒加载单例Bean
	for (String beanName : beanNames) {
	    // Bean定义公共的抽象类是AbstractBeanDefinition,普通的Bean在Spring加载Bean定义的时候,实例化出来的是GenericBeanDefinition
	    // 而Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition
	    // 这时候就使用getMergedLocalBeanDefinition方法做了一次转化,将非RootBeanDefinition转换为RootBeanDefinition以供后续操作。
	    // 注意如果当前BeanDefinition存在父BeanDefinition,会基于父BeanDefinition生成一个RootBeanDefinition,然后再将调用OverrideFrom子BeanDefinition的相关属性覆写进去。
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		// 如果Bean不是抽象的,是单例的,不是懒加载的,则开始创建单例对象通过调用getBean(beanName)方法初始化
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
		    // 判断当前Bean是否实现了FactoryBean接口,如果实现了,判断是否要立即初始化
		    // 判断是否需要立即初始化,根据Bean是否实现了SmartFactoryBean并且重写的内部方法isEagerInit放回true
			if (isFactoryBean(beanName)) {
				final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
				boolean isEagerInit;
				if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
					isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
						public Boolean run() {
							return ((SmartFactoryBean<?>) factory).isEagerInit();
						}
					}, getAccessControlContext());
				}
				else {
					isEagerInit = (factory instanceof SmartFactoryBean &&
							((SmartFactoryBean<?>) factory).isEagerInit());
				}
				if (isEagerInit) {
					getBean(beanName);
				}
			}
			else {
				getBean(beanName);
			}
		}
	}
}

以上代码看似非常多,但是确是走的else模块,也就是直接走的getBean(beanName)方法,所以可以直接往下走,如下:

// 具体getBean函数实现如下所示:
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}

/*
进一步调用了如下方法,其中有参数:
requiredType=null: 一般情况用不到,如果获取到的字符串,但requiredType是Integer,会在最后进行类型转换。
args=null: 在获取prototype对象时传入,用来初始化原型对象
typeCheckOnly=false: 如果为false,会将Bean标志为已创建,记录在alreadyCreated变量中。
*/
protected <T> T doGetBean(
		final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
		throws BeansException {
    // 如果是FactoryBean,会去掉Bean开头的&符号
    // 可能存在传入别名且别名存在多重映射的情况,这里会返回最终的名字,如存在多层别名映射A->B->C->D,传入D,最终会返回A
	final String beanName = transformedBeanName(name);
	Object bean;

	// 这里先尝试从缓存中获取,获取不到再走后面创建的流程
	// 获取到有两种情况,一种是Bean创建完成存储到最终的缓存中。
	// 另一种是未创建完成,但先预存到一个单独的缓存中,这种是针对可能存在循环引用的情况的处理。
	// 如A引用B,B又引用了A,因而在初始化A时,A会先调用构造函数创建出一个实例,在依赖注入B之前,现将A实例缓存起来
	// 然后在初始化A时,依赖注入阶段,会触发初始化B,B创建后需要依赖注入A时,先从缓存中获取A(这个时候的A是不完整的),避免循环依赖的问题出现。
	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 + "'");
			}
		}
		//这里主要处理实现了FactoryBean的情况,需要调用重写的getObject()方法来获取实际的Bean实例。
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	else {
		// 原型对象不允许循环创建,如果是原型对象则抛异常
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// 如果存在父容器,且Bean在父容器中有定义,则通过父容器返回
		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 {
		    // 根据名字获取合并过的对应的RootBeanDefinition
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			// 检查mbd是否为抽象的或mbd为单例,但存在args的情况(args只有初始化原型对象才允许存在)
			checkMergedBeanDefinition(mbd, beanName, args);

			// 确保当前Bean依赖的相关Bean先完成初始化工作
			//在Spring boot中,如果要指定bean的初始化顺序,可以通过@DependsOn(先依赖的类.class)注解指定先初始化的bean
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dependsOnBean : dependsOn) {
					getBean(dependsOnBean);
					registerDependentBean(dependsOnBean, beanName);
				}
			}

			// 前面获取失败,开始创建
			if (mbd.isSingleton()) {
			    // 会先尝试从缓存中获取,获取失败就通过ObjectFactory的createBean方法创建
				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;
						}
					}
				});
				//这里主要处理实现了FactoryBean的情况,需要调用重写的getObject()方法来获取实际的Bean实例。
				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);
				}
				//这里主要处理实现了FactoryBean的情况,需要调用重写的getObject()方法来获取实际的Bean实例。
				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;
		}
	}

	// 检查是否为要求的类型,如果不是则尝试进行类型转换
	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;
}

根据注释,上述源码能够看懂了,关键代码就是这一行:

//返回一个bean的实例
**return createBean(beanName, mbd, args)**

这行在源码中的位置是323行,说实话,有点难找。

唉呀妈呀,还没跟踪到细节,还得往下跟,继续,我们看createBean()方法。

/**
	 * Central method of this class: creates a bean instance,
	 * populates the bean instance, applies post-processors, etc.
	 * @see #doCreateBean
	 */
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		//此类的中心方法:创建一个 bean 实例, 填充 bean 实例,应用后处理器等。
		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		//确保此时实际解析了 bean 类, 
		// 并且克隆 bean 定义以防动态解析的类不能存储在共享的合并 bean 定义中。
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// 如果这个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 {
		    //又是一层嵌套,核心方法
			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);
		}
	}

这个方法主要是在直接创建一个实例前,尝试是否能够创建代理对象返回。继续跟,核心方法就是第517行的doCreateBean方法。这个方法就开始触摸到我们想要看到的东西了,所以,请重点看下

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			// 先尝试从缓存中取
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			// 缓存中没有,就调用构造方法创建一个空实例对象,并用BeanWrapper进行包装
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		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;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		// 如果满足循环引用缓存条件,先缓存具体对象。
		//这里补充一下,Spring 利用三级缓存解决了循环依赖问题
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			// 提前暴露一个单例工厂方法,确保其他Bean能引用到此bean
			// 具体内部会遍历后置处理器,判断是否有SmartInstantiationAwareBeanPostProcessor的实现类,
			//然后调用里面getEarlyBeanReference覆盖当前Bean
			// 默认不做任何操作返回当前Bean,作为拓展,这里可以供AOP来创建代理类
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// 这里注意了,要对bean进行设置属性和初始化了,来喽来喽,鸡汤来喽
		Object exposedObject = bean;
		try {	
			//Spring中Bean的生命周期------设置属性(这里的设置属性就是进行依赖注入)
			populateBean(beanName, mbd, instanceWrapper);
			//Spring中Bean的生命周期------初始化
			// 具体进行了以下操作:
		    	// 1.若实现了BeanNameAware, BeanClassLoaderAware,BeanFactoryAwareAware等接口,则注入相关对象
		    	// 2.遍历后置处理器,调用实现的postProcessBeforeInitialization方法,
		    	// 3.如果实现了initialzingBean,调用实现的 afterPropertiesSet()
		    	// 4.如果配置了init-mothod,调用相应的init方法
		    	// 5.遍历后置处理器,调用实现的postProcessAfterInitialization
			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.");
					}
				}
			}
		}

		// 如果实现了Disposable接口,会在这里进行注册,最后在销毁的时候调用相应的destroy方法
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

上面的源码注释已经把该解释的都解释了,我们的目的也达到了,就是让我们有个概念,Spring生命周期中的实例化、设置属性、初始化到底是在源码的哪里,是怎样的形式体现的。这个顺序是怎么来的,体现在了哪个方法中。至于具体如何进行依赖注入,如何进行初始化的,可以点进去自己看下具体实现。


13、finishRefresh()

最后一步:发布相应的事件。

/**
	 * Finish the refresh of this context, invoking the LifecycleProcessor's
	 * onRefresh() method and publishing the
	 * {@link org.springframework.context.event.ContextRefreshedEvent}.
	 */
	protected void finishRefresh() {
		// 清除上下文级别的资源缓存(例如扫描中的 ASM 元数据)
		clearResourceCaches();

		// 为此上下文初始化生命周期处理器
		initLifecycleProcessor();

		// 2.首先将刷新完毕事件传播到生命周期处理器(触发isAutoStartup方法返回true的SmartLifecycle的start方法)
		getLifecycleProcessor().onRefresh();

		// 推送上下文刷新完毕事件到相应的监听器。
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		LiveBeansView.registerApplicationContext(this);
	}

此方法的最主要作用就是告知所有监听了刷新事件的监听器,刷新完成了,你们可以做想做的事了。

结束

我们要知道Spring的核心是IOC,而AOP都是基于IOC的,所以我们了解了refresh这个IOC的核心方法,对于Spring源码就已经成功了一半了,至于具体如何依赖注入,如何初始化,已经涉及到的各种各样的细节,就是另一半了,把这些细节也弄清楚,Spring源码就可以告一段落了。Spring的源码那么多,最核心的就是这些,我们要学会取舍,根本不可能把Spring中的所有代码看完,那样吃力不讨好。

–我是“道祖且长”,一个在互联网"苟且偷生"的Java程序员
“有任何问题,可评论,我看到就会回复”

你可能感兴趣的:(spring,java,spring,spring,boot)