转载

Spring源码系列之容器启动

Spring源码系列之容器启动

1. Demo创建

  • Demo 代码十分简单,整个工程结构如下:
    Spring源码系列之容器启动
  • pom 依赖
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.8.RELEASE</version>
</dependency>
复制代码
  • service包下的两个类 OrderServiceUserService 只加了 @Service 注解,dao包下的两个类 OrderDaoUserDao 只加了 @Repository 注解。 MainApplication 类中只写 main() 方法。代码如下:
public static void main(String[] args) {
	AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

    UserService userService = applicationContext.getBean(UserService.class);
    System.out.println(userService);

    OrderService orderService = applicationContext.getBean(OrderService.class);
    System.out.println(orderService);

    UserDao userDao = applicationContext.getBean(UserDao.class);
    System.out.println(userDao);

    OrderDao orderDao = applicationContext.getBean(OrderDao.class);
    System.out.println(orderDao);

    applicationContext.close();
}
复制代码
  • AppConfig 类是一个配置类,类上加了两个注解,加 @Configuration 表明 AppConfig 是一个配置类,加 @ComponentScan 是为了告诉 Spring 要扫描哪些包,代码如下:
@Configuration
@ComponentScan("com.tiantang.study")
public class AppConfig {
}
复制代码

2. 启动

  • 运行 MainApplication 中的 main() 方法,这样一个 Spring 容器就运行起来了。控制台分别打印出了 UserServiceOrderServiceUserDaoOrderDaohash 码。
  • 那么问题来了,相比以往 xml 配置的方式,现在就这么几行简单的代码,一个 Spring 容器就能运行起来,我们就能从容器中获取到 BeanSpring 内部是如何做到的呢?下面就来逐步分析 Spring 启动的源码。

3. 入口

  • 程序的入口为 main() 方法,从代码中可以发现,核心代码只有一行, new AnnotationConfigApplicationContext(AppConfig.class) ,通过这一行代码,就将 Spring 容器给创建完成,然后我们就能通过 getBean() 从容器中获取到对象的了。因此,分析 Spring 源码,就从 AnnotationConfigApplicationContext 的有参构造函数开始。
  • AnnotationConfigApplicationContextClassPathXmlApplicationContext 作用一样,前者对应的是采用 JavaConfig 技术的应用,后者对应的是 XML 配置的应用

4. 基础概念

  • 在进行 Spring 源码阅读之前,需要先理解几个概念。
    1. Spring 会将所有交由 Spring 管理的类,扫描其 class 文件,将其解析成 BeanDefinition ,在 BeanDefinition 中会描述类的信息,例如:这个类是否是单例的, Bean 的类型,是否是懒加载,依赖哪些类,自动装配的模型。 Spring 创建对象时,就是根据 BeanDefinition 中的信息来创建 Bean
    1. Spring 容器在本文可以简单理解为 DefaultListableBeanFactory ,它是 BeanFactory 的实现类,这个类有几个非常重要的属性: beanDefinitionMap 是一个 map ,用来存放 bean 所对应的 BeanDefinitionbeanDefinitionNames 是一个 List 集合,用来存放所有 beannamesingletonObjects 是一个 Map ,用来存放所有创建好的单例 Bean
    1. Spring 中有很多后置处理器,但最终可以分为两种,一种是 BeanFactoryPostProcessor ,一种是 BeanPostProcessor 。前者的用途是用来干预 BeanFactory 的创建过程,后者是用来干预 Bean 的创建过程。后置处理器的作用十分重要, bean 的创建以及 AOP 的实现全部依赖后置处理器。

5. AnnotationConfigApplicationContext的构造方法

  • AnnotationConfigApplicationContext 的构造函数的参数,是一个可变数组,可以传多个配置类,在本次 Demo 中,只传了 AppConfig 一个类。
  • 在构造函数中,会先调用 this() ,在 this() 中通过调用父类构造器初始化了 BeanFactory ,以及向容器中注册了7个后置处理器。然后调用 register() ,将构造方法的参数放入到 BeanDefinitionMap 中。最后执行 refresh() 方法,这是整个 Spring 容器启动的核心,本文也将重点分析 refresh() 方法的流程和作用。
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
	// 会初始化一个BeanFactory,为默认的DefaultListableBeanFactory
	// 会初始化一个beanDefinition的读取器,同时向容器中注册了7个spring的后置处理器(包括BeanPostProcessor和BeanFactoryPostProcessor)
	// 会初始化一个扫描器,后面似乎并没有用到这个扫描器,在refresh()中使用的是重新new的一个扫描器。
	this();
	// 将配置类注册进BeanDefinitionMap中
	register(annotatedClasses);
	refresh();
}
复制代码

5.1 this()调用

  • this() 会调用 AnnotationConfigApplicationContext 无参构造方法,而在 Java 的继承中,会先调用父类的构造方法。所以会先调用 AnnotationConfigApplicationContext 的父类 GeniricApplicationContext 的构造方法,在父类中初始化 beanFactory ,即直接 new 了一个 DefaultListableBeanFactory
public GenericApplicationContext() {
	this.beanFactory = new DefaultListableBeanFactory();
}
复制代码
  • this() 中通过 new AnnotatedBeanDefinitionReader(this) 实例化了一个 Bean 读取器,并向 BeanDefinitionMap 中添加了 7 个元素。通过 new ClassPathBeanDefinitionScanner(this) 实例化了一个扫描器(该扫描器在后面并没有用到)。
public AnnotationConfigApplicationContext() {
    // 此处会先调用父类的构造器,即先执行 super(),初始化DefaultListableBeanFactory
    // 初始化了bean的读取器,并向spring中注册了7个spring自带的类,这里的注册指的是将这7个类对应的BeanDefinition放入到到BeanDefinitionMap中
    this.reader = new AnnotatedBeanDefinitionReader(this);
    // 初始化扫描器
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}
复制代码
  • 执行 this.reader = new AnnotatesBeanDefinitionReader(this) 时,最后会调用到 AnnotationConfigUtils.registerAnnotationConfigProcessors(BeanDefinitionRegistry registry,Object source) 方法,这个方法向 BeanDefinitionMap 中添加了 7 个类,这 7 个类的 BeanDefinition (关于 BeanDefinition 的介绍可以参考前面的解释)均为 RootBeanDefinition ,这几个类分别为 ConfigurationClassPostProcessorAutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorRequiredAnnotationBeanPostProcessorPersistenceBeanPostProcessorEventListenerMethodProcessorDefaultEventListenerFactory
  • 这7个类中, ConfigurationClassPostProcessorAutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor 这三个类非常重要,这里先在下面代码中简单介绍了一下作用,后面会单独写文章分析它们的作用。本文的侧重点是先介绍完 Spring 启动的流程。
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {
	DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
	// 省略部分代码 ...
	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
	// 注册ConfigurationClassPostProcessor,这个类超级重要,它完成了对加了Configuration注解类的解析,@ComponentScan、@Import的解析。
	if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
	}
	// 注册AutowiredAnnotationBeanPostProcessor,这个bean的后置处理器用来处理@Autowired的注入
	if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
	}
	// 注册RequiredAnnotationBeanPostProcessor
	if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
	}
	// 注册CommonAnnotationBeanPostProcessor,用来处理如@Resource,@PostConstruct等符合JSR-250规范的注解
	// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
	if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
	}
	// 注册PersistenceAnnotationBeanPostProcessor,来用支持JPA
	// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
	if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition();
		try {
			def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
					AnnotationConfigUtils.class.getClassLoader()));
		}
		catch (ClassNotFoundException ex) {
			throw new IllegalStateException(
					"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
		}
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	// 注册EventListenerMethodProcessor,用来处理方法上加了@EventListener注解的方法
	if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
	}

	// 注册DefaultEventListenerFactory,暂时不知道干啥用的,从类名来看,是一个事件监听器的工厂
	if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
		RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
	}
	return beanDefs;
}
复制代码
  • 调用 this.scanner = new ClassPathBeanDefinitionScanner(this) 来初始化一个扫描器,这个扫描器在后面扫描包的时候,并没有用到,猜测是 Spring 为了满足其他的场景而初始化的,例如: 开发人员手动通过 register(configClass) 时,扫描包时使用的。

5.2 register(annotatedClasses)

将传入的配置类 annotatedClasses 解析成 BeanDefinition (实际类型为 AnnotatedGenericBeanDefinition ),然后放入到 BeanDefinitionMap 中,这样后面在 ConfigurationClassPostProcessor 中能解析 annotatedClasses ,例如 demo 中的 AppConfig 类,只有解析了 AppConfig 类,才能知道 Spring 要扫描哪些包(因为在 AppConfig 类中添加了 @ComponentScan 注解),只有知道要扫描哪些包了,才能扫描出需要交给 Spring 管理的 bean 有哪些,这样才能利用 Spring 来创建 bean

5.3 执行refresh()方法

refresh() 方法是整个 Spring 容器的核心,在这个方法中进行了 bean 的实例化、初始化、自动装配、 AOP 等功能。下面先看看 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.
		// 给beanFactory设置序列化id
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
		// 向beanFactory中注册了两个BeanPostProcessor,以及三个和环境相关的bean
		// 这两个后置处理器为ApplicationContextAwareProcessor和ApplicationListenerDetector
		// 前一个后置处理是为实现了ApplicationContextAware接口的类,回调setApplicationContext()方法,
		// 后一个处理器时用来检测ApplicationListener类的,当某个Bean实现了ApplicationListener接口的bean被创建好后,会被加入到监听器列表中
		prepareBeanFactory(beanFactory);
		try {
			// Allows post-processing of the bean factory in context subclasses.
			// 空方法,由子类实现
			postProcessBeanFactory(beanFactory);
			// 执行所有的BeanFactoryPostProcessor,包括自定义的,以及spring内置的。默认情况下,容器中只有一个BeanFactoryPostProcessor,即:Spring内置的,ConfigurationClassPostProcessor(这个类很重要)
			// 会先执行实现了BeanDefinitionRegistryPostProcessor接口的类,然后执行BeanFactoryPostProcessor的类
			// ConfigurationClassPostProcessor类的postProcessorBeanFactory()方法进行了@Configuration类的解析,@ComponentScan的扫描,以及@Import注解的处理
			// 经过这一步以后,会将所有交由spring管理的bean所对应的BeanDefinition放入到beanFactory的beanDefinitionMap中
			// 同时ConfigurationClassPostProcessor类的postProcessorBeanFactory()方法执行完后,向容器中添加了一个后置处理器————ImportAwareBeanPostProcessor
			invokeBeanFactoryPostProcessors(beanFactory);
			// 注册所有的BeanPostProcessor,因为在方法里面调用了getBean()方法,所以在这一步,实际上已经将所有的BeanPostProcessor实例化了
            // 为什么要在这一步就将BeanPostProcessor实例化呢?因为后面要实例化bean,而BeanPostProcessor是用来干预bean的创建过程的,所以必须在bean实例化之前就实例化所有的BeanPostProcessor(包括开发人员自己定义的)
			// 最后再重新注册了ApplicationListenerDetector,这样做的目的是为了将ApplicationListenerDetector放入到后置处理器的最末端
			registerBeanPostProcessors(beanFactory);
			// Initialize message source for this context.
           // 初始化MessageSource,用来做消息国际化。在一般项目中不会用到消息国际化
			initMessageSource();
			// Initialize event multicaster for this context.
			// 初始化事件广播器,如果容器中存在了名字为applicationEventMulticaster的广播器,则使用该广播器
			// 如果没有,则初始化一个SimpleApplicationEventMulticaster
            // 事件广播器的用途是,发布事件,并且为所发布的时间找到对应的事件监听器。
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			// 执行其他的初始化操作,例如和SpringMVC整合时,需要初始化一些其他的bean,但是对于纯spring工程来说,onFresh方法是一个空方法
			onRefresh();

			// Check for listener beans and register them.
			// 这一步会将自定义的listener的bean名称放入到事件广播器中
			// 同时还会将早期的ApplicationEvent发布(对于单独的spring工程来说,在此时不会有任何ApplicationEvent发布,但是和springMVC整合时,springMVC会执行onRefresh()方法,在这里会发布事件)
			registerListeners();
			// 实例化剩余的非懒加载的单例bean(注意:剩余、非懒加载、单例)
            // 为什么说是剩余呢?如果开发人员自定义了BeanPosrProcessor,而BeanPostProcessor在前面已经实例化了,所以在这里不会再实例化,因此这里使用剩余一词
			finishBeanFactoryInitialization(beanFactory);
			// 结束refresh,主要干了一件事,就是发布一个事件ContextRefreshEvent,通知大家spring容器refresh结束了。
			finishRefresh();
		}
		catch (BeansException ex) {
			// 出异常后销毁bean
			destroyBeans();
			// Reset 'active' flag.
			cancelRefresh(ex);
			// Propagate exception to caller.
			throw ex;
		}
		finally {
           // 在bean的实例化过程中,会缓存很多信息,例如bean的注解信息,但是当单例bean实例化完成后,这些缓存信息已经不会再使用了,所以可以释放这些内存资源了
			resetCommonCaches();
		}
	}
}
复制代码

6. refresh()方法

  • refresh() 方法中,比较重要的方法为 invokeBeanFactoryPostProcessors(beanFactory)finishBeanFactoryInitialization(beanFactory) 。其他的方法相对而言比较简单,下面主要分析这两个方法,其他方法的作用,可以参考上面源码中的注释。

6.1 invokeBeanFactoryPostProcessors()

  • 该方法的作用是执行所有的 BeanFactoryPostProcessor ,由于 Spring 会内置一个 BeanFactoryPostProcessor ,即 ConfigurationClassPostProcessor (如果开发人员不自定义,默认情况下只有这一个 BeanFactoryPostProcessor ),这个后置处理器在处理时,会解析出所有交由 Spring 容器管理的 Bean ,将它们解析成 BeanDefinition ,然后放入到 BeanFactoryBeanDefinitionMap 中。
  • 该方法最终会调用到 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors() 方法,主要作用是执行所有 BeanFactoryPostProcessorpostProcessorBeanFactory() 方法。 BeanFactoryPostProcessor 又分为两种情况,一种是直接实现 BeanFactoryPostProcessor 接口的类,另一种情况是实现了 BeanDefinitionRegistryPostProcessor 接口( BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor 接口)。
    Spring源码系列之容器启动
  • 在执行过程中先执行所有的 BeanDefinitionRegistryPostProcessorpostProcessorBeanDefinitionRegistry() 方法,然后再执行 BeanFacotryPostProcessorpostProcessorBeanFactory() 方法。
public interface BeanFactoryPostProcessor {
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
复制代码
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
复制代码
  • 默认情况下, Spring 有一个内置的 BeanFactoryPostProcessor ,即: ConfigurationClassPostProcessor 类,该类实现了 BeanDefinitionRegistryPostProcessor 类,所以会执行 ConfigurationClassPostProcessor.postProcessorBeanDefinitionRegistry , ConfigurationClassPostProcessorUML 图如上(删减了部分不重要的继承关系)

6.2 registerBeanPostProcessors()

  • 该方法的作用是找到所有的 BeanPostProcessor ,然后将这些 BeanPostProcessor 实例化(会调用 getBean() 方法, getBean() 方法的主要逻辑是,如果 bean 存在于 BeanFactory 中,则返回 bean ;如果不存在,则会去创建。在后面会仔细分析 getBean() 的执行逻辑)。将这些 PostProcessor 实例化后,最后放入到 BeanFactorybeanPostProcessors 属性中。
  • 问题:如何找到所有的 BeanPostProcessor ? 包括 Spring 内置的和开发人员自定义的。
  • 由于在 refresh() 方法中,会先执行完 invokeBeanFactoryPostProcessor() 方法,这样所有自定义的 BeanPostProcessor 类均已经被扫描出并解析成 BeanDefinition (扫描和解析又是谁做的呢? ConfigurationClassPostProcessor 做的),存入至 BeanFactoryBeanDefinitionMap ,所以这儿能通过方法如下一行代码找出所有的 BeanPostProcessor ,然后通过 getBean() 全部实例化,最后再将实例化后的对象加入到 BeanFactorybeanPostProcessors 属性中,该属性是一个 List 集合。
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
复制代码
  • 最后再重新注册了 ApplicationListenerDetector ,这样做的目的是为了将 ApplicationListenerDetector 放入到后置处理器的最末端
  • registerBeanPostProcessor() 最终调用的是 PostProcessorRegistrationDelegate.registerBeanPostProcessors() ,下面是 PostProcessorRegistrationDelegate.registerBeanPostProcessors() 方法的代码
public static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

	// 从BeanDefinitionMap中找出所有的BeanPostProcessor
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
	// ... 省略部分代码 ...

	// 分别找出实现了PriorityOrdered、Ordered接口以及普通的BeanPostProcessor
	for (String ppName : postProcessorNames) {
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			// 此处调用了getBean()方法,因此在此处就会实例化出BeanPostProcessor
			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);
	// 将实现了PriorityOrdered接口的BeanPostProcessor添加到BeanFactory的beanPostProcessors集合中
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// 下面这部分代码与上面的代码逻辑一致,是将实现了Ordered接口以及普通的BeanPostProcessor实例化以及添加到beanPostProcessors结合中,逻辑与处理PriorityOrdered的后置处理器一样
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
	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<>();
	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));

	// 最后将ApplicationListenerDetector这个后置处理器一样重新放入到beanPostProcessor中,这样做的目的是为了将其放入到后置处理器的最末端
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
复制代码
  • 从上面的源码中可以发现, BeanPostProcessor 存在优先级,实现了 PriorityOrdered 接口的优先级最高,其次是 Ordered 接口,最后是普通的 BeanPostProcessor 。优先级最高的,会最先放入到 beanPostProcessors 这个集合的最前面,这样在执行时,会最先执行优先级最高的后置处理器(因为 List 集合是有序的)。
  • 这样在实际应用中,如果我们碰到需要优先让某个 BeanPostProcessor 执行,则可以让其实现 PriorityOrdered 接口或者 Ordered 接口。

6.3 initMessageSource()

  • 用来支持消息国际化,现在一般项目中不会用到国际化相关的知识。

6.4 initApplicationEventMulticaster()

该方法初始化了一个事件广播器,如果容器中存在了 beanNameapplicationEventMulticaster 的广播器,则使用该广播器;如果没有,则初始化一个 SimpleApplicationEventMulticaster 。该事件广播器是用来做应用事件分发的,这个类会持有所有的事件监听器( ApplicationListener ),当有 ApplicationEvent 事件发布时,该事件监听器能根据事件类型,检索到对该事件感兴趣的 ApplicationListener

  • initApplicationEventMulticaster() 方法的源码如下(省略了部分日志信息):
protected void initApplicationEventMulticaster() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	// 判断spring容器中是否已经存在beanName = applicationEventMulticaster的事件广播器
	// 例如:如果开发人员自己注册了一个
	// 如果存在,则使用已经存在的;否则使用spring默认的:SimpleApplicationEventMulticaster
	if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
		this.applicationEventMulticaster =
				beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
	}
	else {
		this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
		beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
	}
}
复制代码

6.5 onRefresh()

执行其他的初始化操作,例如和 SpringMVC 整合时,需要初始化一些其他的 bean ,但是对于纯 Spring 工程来说, onRefresh() 方法是一个空方法。

6.6 registerListeners()

这一步会将自定义的 listenerbean 名称放入到事件广播器中,同时还会将早期的 ApplicationEvent 发布(对于单独的 Spring 工程来说,在此时不会有任何 ApplicationEvent 发布,但是和 SpringMVC 整合时, SpringMVC 会执行 onRefresh() 方法,在这里会发布事件)。方法源码如下:

protected void registerListeners() {
	// Register statically specified listeners first.
	for (ApplicationListener<?> listener : getApplicationListeners()) {
  getApplicationEventMulticaster().addApplicationListener(listener);
	}

	// 从BeanFactory中找到所有的ApplicationListener,但是不会进行初始化,因为需要在后面bean实例化的过程中,让所有的BeanPostProcessor去改造它们
	String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
	for (String listenerBeanName : listenerBeanNames) {
		// 将事件监听器的beanName放入到事件广播器中
		getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
	}

	// 发布早期的事件(纯的spring工程,在此时一个事件都没有)
	Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
	this.earlyApplicationEvents = null;
	if (earlyEventsToProcess != null) {
		for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
			getApplicationEventMulticaster().multicastEvent(earlyEvent);
		}
	}
}
复制代码

6.7 finishBeanFactoryInitialization()

该方法十分重要,它完成了所有非懒加载的单例 Bean 的实例化和初始化,属性的填充以及解决了循环依赖等问题。

  • (注意这里特意将对象的实例化和初始化过程分开了,因为在 Spring 创建 Bean 的过程中,是先将 Bean 通过反射创建对象,然后通过后置处理器( BeanPostProcessor )来为对象的属性赋值。所以这里的实例化时指将 Bean 创建出来,初始化是指为 bean 的属性赋值)。
  • finishBeanFactoryInitialization() 方法的代码如下, bean 的创建和初始化均在 beanFactory.preInstantiateSingletons() 中实现。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// 初始化转换服务
	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));
	}
	// 如果前面没有注册一个类似于PropertyPlaceholderConfigurer后置处理器的bean,那么在这儿会注册一个内置的属性后置处理器
	// 这儿主要是处理被加了注解的属性
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
	}
	// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}
	beanFactory.setTempClassLoader(null);
	// 将BeanFactory的configurationFrozen属性设置为true,给frozenBeanDefinitionNames属性赋值
	// 目的是为了不让在其他的地方在修改bean的BeanDefinition
	beanFactory.freezeConfiguration();

	// Instantiate all remaining (non-lazy-init) singletons.
	// 实例化剩下所有的非懒加载的单例
	beanFactory.preInstantiateSingletons();
}
复制代码

6.7.1 preInstantiateSingletons()方法

  • 该方法会先判断 bean 是否是一个 FactoryBean ,以及是否立即实例化 FactoryBeangetObject() 返回的对象,但最终均是调用 getBean() 方法去实例化对象。在 Bean 实例化、初始化完成后,会判断 Bean 是否实现了 SmartSingletonInitializing 接口,如果实现了,则会调用该接口的 afterSingletonInstantiated() 方法。
  • Tips :这里提到了 FactoryBean ,不是 BeanFactory 。这两者名字很像,但作用却是天差地别,有兴趣的朋友可以先自己 Google 查下相关知识。这里先简单介绍一下,后续会单独写一篇文章介绍 FactoryBean ,并通过 FactoryBean 去解析 SpringMyBatis 整合的原理。
  • FactoryBean 是一个接口,该接口的实现类会向容器中注册两个 bean ,一个是实现类本身所代表类型的对象,一个是通过重写 FactoryBean 接口中 getObject() 方法所返回的 bean 。如下例子中:会向容器中注册两个 bean ,一个是 MapperFactoryBean 本身,一个是 UserMapper
@Component
public class MapperFactoryBean implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        return new UserMapper();
    }

    @Override
    public Class<?> getObjectType() {
        return UserMapper.class;
    }
}
复制代码
  • 由于 bean 的实例化过程太过复杂,后面会结合流程图去分析源码。 preInstantiatedSingletons() 方法的执行流程图如下
    Spring源码系列之容器启动
  • preInstantiatedSingletons() 代码如下
public void preInstantiateSingletons() throws BeansException {
	if (logger.isDebugEnabled()) {
		logger.debug("Pre-instantiating singletons in " + this);
	}
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
	// Trigger initialization of all non-lazy singleton beans...
	for (String beanName : beanNames) {
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// 判断是否是factoryBean,如果是FactoryBean,则进行FactoryBean原生的实例化(非getObject()方法对应的对象)。
			// 还需要判断它是否立即实例化getObject()返回的对象,根据SmartFactoryBean的isEagerInit()的返回值判断是否需要立即实例化
			if (isFactoryBean(beanName)) {
				// 首先实例化BeanFactory的原生对象,然后再根据isEagerInit()判断是否实例化BeanFactory中getObject()返回的类型的对象
				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
				if (bean instanceof FactoryBean) {
					final FactoryBean<?> factory = (FactoryBean<?>) bean;
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
										((SmartFactoryBean<?>) factory)::isEagerInit,
								getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					// 如果isEagerInit为true,则立即实例化FactoryBean所返回的类型的对象
					if (isEagerInit) {
						getBean(beanName);
					}
				}
			}
			else {
				getBean(beanName);
			}
		}
	}
	// 在bean实例化以及属性赋值完成后,如果bean实现了SmartInitializingSingleton接口,则回调该接口的方法
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			}
			else {
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}
复制代码
  • 从上面源码中发现,不论是 FactoryBean 还是普通 Bean ,最终都是调用 getBean() 方法去创建 bean

6.7.2 getBean()

  • getBean() 方法会调用 doGetBean() 方法。
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}
复制代码

6.7.3 doGetBean()

  • doGetBean() 方法当中,会先从缓存中获取(即从 singletonObjects 这个 map 集合中获取,为什么要先从缓存中获取呢?因为要从 Spring 容器获取对象和创建对象,都是通过 getBean() 方法,对于单例对象而言,对象只会被创建一次,那么先从缓存中获取对象,如果存在,则不用去新创建了,这样就保证了单例对象只被创建一次)。如果缓存中存在,则接着调用 getObjectForBeanInstance() 方法,然后返回 bean 。如果缓存中不存在,则继续往下执行。
  • 然后获取到 Bean 所对应的 BeanDefinition 对象。接着判断 bean 有没有依赖, String[] dependsOn = mbd.getDependsOn() ,如果有依赖的对象,那么会先去实例化依赖的对象。
  • 依赖的对象创建完成后,会调用 getSingleton(beanName,lambda) 方法,这个方法的第二个参数是一个 lambda 表达式,真正创建 bean 的逻辑是在表达式的方法体中,即 createBean() 方法, createBean() 方法会创建完成 bean ,然后在 getSingleton(beanName,lambda) 方法中会将创建完成的 bean 存入到 singletonObjects 属性中。 createBean() 后面分析。
  • 在上一步创建完 bean 后,最终仍会调用 getObjectForBeanInstance() 。这个方法的逻辑比较简单,先判断 bean 是否是一个 FactoryBean ,若不是,则直接返回 bean ;若是,则再判断 beanName 是否是以&符号开头,如果是,表示获取的是 FactoryBean 的原生对象,则直接返回 bean ;若不是以&符号开头,则会返回 FactoryBeangetObject() 方法的返回值对象。
  • doGetBean() 方法代码如下
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
		@Nullable 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) {
		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 (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if (args != null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else {
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
		}
		if (!typeCheckOnly) {
			// 标记bean为已创建
			// 并清除beanDefinition的缓存(mergedBeanDefinitions)
			markBeanAsCreated(beanName);
		}
		try {
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			// 检查bean是否是抽象类
			checkMergedBeanDefinition(mbd, beanName, args);
			// Guarantee initialization of beans that the current bean depends on.
			// 保证当前bean所依赖的bean初始化
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dep : dependsOn) {
					// isDependent()方法用来判断dep是否依赖beanName
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					// 保存下依赖关系
					registerDependentBean(dep, beanName);
					try {
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}
			// Create bean instance.
			if (mbd.isSingleton()) {
				// 此时在getSingleton方法中传入了一个lambda表达式,
				// 此时不会立即执行lambda表达式,而是在调用这个lambda表达式的getObject()方法时才开始执行lambda的方法体
				sharedInstance = getSingleton(beanName, () -> {
					try {
						return createBean(beanName, mbd, args);
					}
					catch (BeansException ex) {
						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, () -> {
						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 && !requiredType.isInstance(bean)) {
		try {
			T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
			return convertedBean;
		}
		catch (TypeMismatchException ex) {
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}
	return (T) bean;
}
复制代码
  • getObjectForBeanInstance() 方法的作用是为了根据 beanName 来判断是返回 FactoryBean 原生对象还是 getObject() 方法所返回的对象.若 beanName 以&符号开头,则表示返回 FactoryBean 原生对象,否则返回 getObject() 方法所返回的对象。
protected Object getObjectForBeanInstance(
		Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
	if (BeanFactoryUtils.isFactoryDereference(name)) {
		if (beanInstance instanceof NullBean) {
			return beanInstance;
		}
		if (!(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
		}
	}

	// 如果不是一个FactoryBean对象或者是获取FactoryBean的原生对象(原生对象指的是beanName是以&开头)
	// 此时可以直接返回bean
	if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
		return beanInstance;
	}

	// 如果是获取FactoryBean的getObject()方法返回的类型对象,则需要进入到如下逻辑
	// 对于getObject()方法,它返回的对象是在在第一次调用getObject方法时进行实例化的,实例化完成以后,会将结果缓存在factoryBeanObjectCache中
	Object object = null;
	if (mbd == null) {
		object = getCachedObjectForFactoryBean(beanName);
	}
	if (object == null) {
		// Return bean instance from factory.
		FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
		// Caches object obtained from FactoryBean if it is a singleton.
		if (mbd == null && containsBeanDefinition(beanName)) {
			mbd = getMergedLocalBeanDefinition(beanName);
		}
		boolean synthetic = (mbd != null && mbd.isSynthetic());
		// 获取FactoryBean返回的对象
		object = getObjectFromFactoryBean(factory, beanName, !synthetic);
	}
	return object;
}
复制代码

6.7.4 createBean()

  • doGetBean() 最终会调用 createBean() 来创建 bean
  • createBean() 方法的代码中,主要有两行核心代码:
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
复制代码
  • resolveBeforeInstantiation() 方法在 bean 实例化之前调用,在这个方法中执行了后置处理器 InstantiationAwareBeanPostProcessorpostProcessBeforeInstantiation() 方法,在 bean 实例化之前对 bean 进行处理。这个扩展点的意义十分重大, SpringAOP 就是在这儿实现的,感兴趣的朋友可阅读 AnnotationAwareAspectJAutoProxyCreator 这个类的源码,后续会单独写一篇文章进行分析。
  • 如果 resolveBeforeInstantiation() 的返回值不为 null ,则直接将结果返回。如果为 null ,则会继续执行方法 doCreateBean() 。在 doCreateBean() 方法中,进行了 Bean 的实例化、属性赋值、初始化等操作。
  • createBean() 方法的流程图
    Spring源码系列之容器启动
  • createBean() 方法的源代码
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {
	RootBeanDefinition mbdToUse = mbd;
	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.
	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 {
		// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
		// 第一次调用后置处理器(执行所有InstantiationAwareBeanPostProcessor的子类)
		// 如果InstantiationAwareBeanPostProcessor的子类的postProcessBeforeInstantiation()方法返回值不为空,表示bean需要被增强,
		// 此时将不会执行后面的逻辑,AOP的实际应用就是在这儿实现的
		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.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
	catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
		throw ex;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
	}
}
复制代码

6.7.5 doCreateBean()

  • doCreateBean() 方法会通过反射进行 Bean 的创建,然后对 bean 进行属性填充(在填充属性的同时,解决了循环依赖的问题),最后会对 Bean 回调初始化相关的方法,例如: BeanPostProcessor.postProcessBeforeInilization(),InilizaingBean.afterPropertiesSet() ,给 bean 配置的 initMethod() 方法,以及 BeanPostProcessor.postProcessAfterInilization()
  • doCreateBean() 执行的流程图如下: ![doCreateBean()方法流程图] user-gold-cdn.xitu.io/2019/9/11/1… )
  • 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) {
		// 实例化bean(第二次执行后置处理器的入口),第二次执行后置处理器,主要是为了推断出实例化Bean所需要的构造器
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}
	// 此时bean对象已经创建成功,但是没有设置属性和经过其他后置处理器处理
	// Allow post-processors to modify the merged bean definition.
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				// 第三次执行后置处理器,缓存bean的注解元数据信息(用于后面在进行属性填充时使用)
				// 这一步对于CommonAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor这一类处理器
				// 主要是将bean的注解信息解析出来,然后缓存到后置处理器中的injectionMetadataCache属性中
				// 而对于ApplicationListenerDetector处理器,而是将bean是否是单例的标识存于singletonNames这个Map类型的属性中
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			mbd.postProcessed = true;
		}
	}
	// 判断一个bean是否放入到singletonFactories中(提前暴露出来,可以解决循环依赖的问题)
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		// 第四次出现后置处理器
		// 获取提前暴露的对象,可以解决循环引用的问题,实际上提前暴露出来的bean是放入到了singletonFactories中,key是beanName,value是一个lambda表达式
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}
	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		// 填充属性,第五次、第六次后置处理器入口
		populateBean(beanName, mbd, instanceWrapper);
		// 第七次、第八次执行后置处理器入口
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
	}
	return exposedObject;
}
复制代码
  • createBeanInstance() 会通过反射创建对象时,会先执行后置处理器,通过调用后置处理器的 deternineCondidateConstructors() 方法来推断出使用哪一个构造器来创建 Bean ,典型的代表类有 AutowiredAnnotationBeanPostProcessor
  • bean 被通过反射创建完成后,会再次调用后置处理器 MergedBeanDefinitionPostProcessor.postProcessMargedBeanDefinition() 方法,这一步执行后置处理器的目的是为了找出加了 @Autowired@Resource 等注解的属性和方法,然后将这些注解信息缓存到 injectionMetadataCache 属性中,便于后面在 bean 初始化阶段(属性赋值阶段),根据 @Autowired 等注解实现自动装配。这一步的代表后置处理器有 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor 是用来处理 Spring 提供的注解和 JSR-330 中的部分注解,如: @Autowired@Value@InjectCommonAnnotationBeanPostProcessor 是用来处理 JSR-250 中的注解,如 @Resource@PostConstruct@PreDestroy

  • 接下来会将半成品的 bean (因为此时还未给 bean 的属性赋值,未完成自动装配,因此称之为半成品)放入到 DefaultSingletonBeanRegistry 类的 singletonFactories 的属性中, singletonFactories 属性是一个 MapkeybeanName ,值为 ObjectFactory 类型(实际上就是一个 lambda 表达式),当调用 ObjectFactorygetObject() 方法时,会执行 lambda 表达式的方法体,在当前场景下, lambda 表达式的代码如下,实际上就是执行了一次 Bean 的后置处理器。这一步的目的是为了解决 bean 之间的循环依赖,究竟是如何解决循环依赖的,以后分析。
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
	Object exposedObject = bean;
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                // 调用后置处理的方法获取bean早期暴露出来的bean对象(半成品)
				exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
			}
		}
	}
	return exposedObject;
}
复制代码
  • 然后会执行到 populateBean() 方法,在该方法中又会执行两次 Bean 后置处理器,第一次执行后置处理器是为了判断 Bean 是否需要继续填充属性,如果 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() 方法返回的 false ,则表示不进行属性填充, bean 就不会进行 @Autowired 等自动装配过程, populateBean() 方法会直接结束。若返回 true ,则会进行接下来的属性填充,即会执行第二次后置处理器, InstantiationAwareBeanPostProcessor.postProcessPropertyValue() 方法,这一步的主角就是 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostBeanPostProcessor 了,它们会根据前面缓存在 injectionMetadataCache 中的注解信息来进行自动装配。
  • 在执行完 populateBean() 方法后后,接下来回执行 initializeBean() 方法,即进入初始化阶段。在 initializeBean() 方法中,最先执行 invokeAwareMethods() 方法,即执行 Aware 接口的方法,如: BeanNameAwareBeanClassLoaderAwareBeanFactoryAware 。然后再一次执行所有 Bean 后置处理器的 BeanPostProcessor.postProcessBeforeInitialization() 方法。接着执行 invokeInitMethods() 方法,在 invokeInitMethods() 方法中,会执行 InitializingBeanafterPropertiesSet() 方法,和定义 bean 时自定义的 initMethod() 方法。最后再一次执行 bean 后置处理器, BeanPostProcessor.postProcessAfterInitialization()
  • 至此 bean 的实例化、初始化过程已经完成,创建好的 bean 会被返回,若是单例 bean ,最后会被存放到 DefaultSingletonBeanRegistrysingletonObjects 中。

6.8 finishRefresh()

  • 执行到这一步, Spring 容器的启动基本结束了,此时 Bean 已经被实例化完成,且完成了自动装配。执行 finishRefresh() 方法,是为了在容器 refresh() 结束时,做一些其他的操作,例如:发布 ContextRefreshedEvent 事件,这样当我们想在容器 refresh 完成后执行一些特殊的逻辑,就可以通过监听 ContextRefreshedEvent 事件来实现。 Spring 内置了四个和应用上下文( ApplicationContextEvent )有关的事件: ContextRefreshedEventContextStartedEventContextStopedEventContextClosedEvent
protected void finishRefresh() {
    clearResourceCaches();
    initLifecycleProcessor();
    getLifecycleProcessor().onRefresh();
    // 发布ContextRefreshedEvent
    publishEvent(new ContextRefreshedEvent(this));
    LiveBeansView.registerApplicationContext(this˛);
}
复制代码

6.9 resetCommonCaches()

最后在 refresh() 方法的 finally 语句块中,执行了 resetCommonCaches() 方法。因为在前面创建 bean 时,对单例 bean 的元数据信息进行了缓存,而单例 bean 在容器启动后,不会再进行创建了,因此这些缓存的信息已经没有任何用处了,在这里进行清空,释放部分内存。

protected void resetCommonCaches() {
    ReflectionUtils.clearCache();
    AnnotationUtils.clearCache();
    ResolvableType.clearCache();
    CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
复制代码

7. Bean生命周期

  • 从上面 Spring 的源码分析中,可以看出,启动过程中, bean 的创建过程最为复杂,在创建过程中,前后一共出现了8次调用 BeanPostPorcessor (实际上在 bean 的整个生命周期中,一共会出现 9 次调用后置处理器,第九次出现在 bean 的销毁阶段。)
  • 结合 Spring 的源码,单例 bean 的生命周期可以总结为如下一张图
    Spring源码系列之容器启动

8. 总结

  • 本文介绍了 Spring 的启动流程,通过 AnnotationConfigApplicationContext 的有参构造方法入手,重点分析了 this() 方法和 refresh() 方法。在 this() 中初始化了一个 BeanFactory ,即 DefaultListableBeanFactory ;然后向容器中添加了7个内置的 bean ,其中就包括 ConfigurationClassPostProcessor
  • refresh() 方法中,又重点分析了 invokeBeanFactoryPostProcessor() 方法和 finishBeanFactoryInitialization() 方法。
  • invokeBeanFactoryPostProcessor() 方法中,通过 ConfigurationClassPostProcessor 类扫描出了所有交给 Spring 管理的类,并将 class 文件解析成对应的 BeanDefinition
  • finishBeanFactoryInitialization() 方法中,完成了非懒加载的单例 Bean 的实例化和初始化操作,主要流程为 getBean() ——> doGetBean() ——> createBean() ——> doCreateBean() 。在 bean 的创建过程中,一共出现了 8BeanPostProcessor 的执行,在这些后置处理器的执行过程中,完成了 AOP 的实现、 bean 的自动装配、属性赋值等操作。
  • 最后通过一张流程图,总结了 Spring 中单例 Bean 的生命周期。

9. 计划

本文主要介绍了 Spring 的启动流程,但对于一些地方的具体实现细节没有展开分析,因此后续Spring源码分析的计划如下:

  • ConfigurationClassPostProcessor 类如何扫描包,解析配置类。
  • @Import 注解作用与 @Enable 系列注解的实现原理
  • JDK 动态代理与 CGLIB 代理
  • FactoryBean 的用途和源码分析
  • AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor 如何实现自动装配, Spring 如何解决循环依赖
  • AOP 的实现原理
  • SpringBoot 源码分析

10. 推荐性能监控工具

  • 最后推荐一款开源的性能监控工具—— Pepper-Metrics

地址: github.com/zrbcool/pep… GitHub Pepper-Metrics 是坐我对面的两位同事一起开发的开源组件,主要功能是通过比较轻量的方式与常用开源组件( jedis/mybatis/motan/dubbo/servlet )集成,收集并计算 metrics ,并支持输出到日志及转换成多种时序数据库兼容数据格式,配套的 grafana dashboard 友好的进行展示。项目当中原理文档齐全,且全部基于 SPI 设计的可扩展式架构,方便的开发新插件。另有一个基于 docker-compose 的独立 demo 项目可以快速启动一套 demo 示例查看效果 https://github.com/zrbcool/pepper-metrics-demo 。如果大家觉得有用的话,麻烦给个 star ,也欢迎大家参与开发,谢谢:)

欢迎扫描下方二维码,关注微信公众号:菜鸟飞呀飞 阅读更多源码,不再面向搜索引擎编程

Spring源码系列之容器启动
原文  https://juejin.im/post/5d791686e51d4561d044cd61
正文到此结束
Loading...