【Spring】Spring之启动过程源码解析

概述

我们说的Spring启动,就是构造ApplicationContext对象以及调用refresh()方法的过程。

Spring启动过程主要做了这么几件事情:

  1. 构造一个BeanFactory对象
  2. 解析配置类,得到BeanDefinition,并注册到BeanFactory中
    1. 解析@ComponentScan,此时就会完成扫描
    2. 解析@Import
    3. 解析@Bean
  3. ApplicationContext支持国际化,需要初始化MessageSource对象
  4. ApplicationContext支持事件机制,需要初始化ApplicationEventMulticaster对象
  5. 把用户定义的ApplicationListener对象添加到ApplicationContext中,等Spring启动完了发布事件
  6. 创建非懒加载的单例Bean对象,并存在BeanFactory的单例池中
  7. 调用Lifecycle Bean的start()方法
  8. 发布ContextRefreshedEvent事件

Spring启动过程中要创建非懒加载的单例Bean对象,需要用到BeanPostProcessor,所以Spring在启动过程中需要做两件事:

  1. 生成默认的BeanPostProcessor对象,并添加到BeanFactory中
    1. AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value
    2. CommonAnnotationBeanPostProcessor:处理@Resource、@PostConstruct、@PreDestroy
    3. ApplicationContextAwareProcessor:处理ApplicationContextAware等回调
  2. 找到外部用户所定义的BeanPostProcessor对象(类型为BeanPostProcessor的Bean对象),并添加到BeanFactory中

BeanFactoryPostProcessor

BeanPostProcessor表示Bean的后置处理器,是用来对Bean进行加工的,类似的,BeanFactoryPostProcessor理解为BeanFactory的后置处理器,用来用对BeanFactory进行加工的。

Spring支持用户定义BeanFactoryPostProcessor的实现类Bean,来对BeanFactory进行加工,比如:

@Component
public class FireBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
		// 修改BeanDefinition对象的属性值,发生在Spring启动时,创建单例Bean之前,后面创建Bean时此处的修改会生效
        beanDefinition.setAutowireCandidate(false);
	}
}

在ApplicationContext内部有一个核心的DefaultListableBeanFactory,它实现了ConfigurableListableBeanFactory和BeanDefinitionRegistry接口,所以ApplicationContext和DefaultListableBeanFactory是可以注册BeanDefinition的,但是ConfigurableListableBeanFactory是不能注册BeanDefinition的,只能获取BeanDefinition,然后做修改。

// AnnotationConfigApplicationContext继承GenericApplicationContext
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

	private final DefaultListableBeanFactory beanFactory;

    ...
}

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    // ConfigurableListableBeanFactory只能获取BeanDefinition,不能注册BeanDefinition
    ...
}

Spring提供了一个BeanFactoryPostProcessor的子接口:BeanDefinitionRegistryPostProcessor,用以注册BeanDefinition对象。

BeanDefinitionRegistryPostProcessor

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
	// 实现该接口并实现该方法,可以注册BeanDefinition对象
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

自定义类注册BeanDefinition,例如:

@Component
public class FireBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
		beanDefinition.setBeanClass(User.class);
		registry.registerBeanDefinition("user", beanDefinition);
	}

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
		beanDefinition.setAutowireCandidate(false);
	}
}

refresh()

构造ApplicationContext对象时,调用refresh()方法,如下:

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    // 构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
    this();
    register(componentClasses);
    refresh();
}

refresh()是在接口ConfigurableApplicationContext中定义的,如下:

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
    /**
     * Load or refresh the persistent representation of the configuration, which
     * might be from Java-based configuration, an XML file, a properties file, a
     * relational database schema, or some other format.
     * 

As this is a startup method, it should destroy already created singletons * if it fails, to avoid dangling resources. In other words, after invocation * of this method, either all or no singletons at all should be instantiated. * @throws BeansException if the bean factory could not be initialized * @throws IllegalStateException if already initialized and multiple refresh * attempts are not supported */ void refresh() throws BeansException, IllegalStateException; }

注释意思是:加载或刷新持久化的配置,可能是XML文件、属性文件或关系数据库中存储的。由于这是一个启动方法,如果失败,它应该销毁已经创建的单例,以避免占用资源。换句话说,在调用该方法之后,应该实例化所有的单例,或者根本不实例化单例 。
注意:ApplicationContext关闭之后不代表JVM也关闭了,ApplicationContext是属于JVM的,说白了ApplicationContext也是JVM中的一个对象。

有两种ApplicationContext,分为可刷新和不可刷新(只能刷新一次,不能重复刷新),如下:

// 刷新的ApplicationContext
AbstractRefreshableApplicationContext extends AbstractApplicationContext
// 不可刷新的ApplicationContext
GenericApplicationContext extends AbstractApplicationContext

AnnotationConfigApplicationContext继承的是GenericApplicationContext,所以它是不能刷新的。
AnnotationConfigWebApplicationContext继承的是AbstractRefreshableWebApplicationContext,所以它是可以刷新的。

下面以AnnotationConfigApplicationContext为例子,来介绍refresh的底层实现流程:

  1. 在调用AnnotationConfigApplicationContext的构造方法之前,会调用父类GenericApplicationContext的无参构造方法,会构造一个BeanFactory,为DefaultListableBeanFactory
  2. 构造AnnotatedBeanDefinitionReader(主要作用添加一些基础的PostProcessor,同时可以通过reader进行BeanDefinition的注册),同时对BeanFactory进行设置和添加PostProcessor(后置处理器)
    1. 设置dependencyComparator:AnnotationAwareOrderComparator,它是一个Comparator,是用来进行排序的,会获取某个对象上的Order注解或者通过实现Ordered接口所定义的值进行排序,在日常开发中可以利用这个类来进行排序
    2. 设置autowireCandidateResolver:ContextAnnotationAutowireCandidateResolver,用来解析某个Bean能不能进行自动注入,比如某个Bean的autowireCandidate属性是否等于true
    3. 向BeanFactory中添加ConfigurationClassPostProcessor对应的BeanDefinition,它是一个BeanDefinitionRegistryPostProcessor,并且实现了PriorityOrdered接口
    4. 向BeanFactory中添加AutowiredAnnotationBeanPostProcessor对应的BeanDefinition,它是一个InstantiationAwareBeanPostProcessorAdapter,MergedBeanDefinitionPostProcessor
    5. 向BeanFactory中添加CommonAnnotationBeanPostProcessor对应的BeanDefinition,它是一个InstantiationAwareBeanPostProcessor,InitDestroyAnnotationBeanPostProcessor
    6. 向BeanFactory中添加EventListenerMethodProcessor对应的BeanDefinition,它是一个BeanFactoryPostProcessor,SmartInitializingSingleton
    7. 向BeanFactory中添加DefaultEventListenerFactory对应的BeanDefinition,它是一个EventListenerFactory
  3. 构造ClassPathBeanDefinitionScanner(主要作用可以用来扫描得到并注册BeanDefinition),同时进行设置:
    1. 设置this.includeFilters = AnnotationTypeFilter(Component.class)
    2. 设置environment
    3. 设置resourceLoader
  4. 利用reader注册AppConfig为BeanDefinition,类型为AnnotatedGenericBeanDefinition
  5. 接下来就是调用refresh方法
  6. prepareRefresh():
    1. 记录启动时间
    2. 可以允许子容器设置一些内容到Environment中
    3. 验证Environment中是否包括了必须要有的属性
  7. obtainFreshBeanFactory():进行BeanFactory的refresh,在这里会去调用子类的refreshBeanFactory方法,具体子类是怎么刷新的得看子类,然后再调用子类的getBeanFactory方法,重新得到一个BeanFactory
  8. prepareBeanFactory(beanFactory):
    1. 设置beanFactory的类加载器
    2. 设置表达式解析器:StandardBeanExpressionResolver,用来解析Spring中的表达式
    3. 添加PropertyEditorRegistrar:ResourceEditorRegistrar,PropertyEditor类型转化器注册器,用来注册一些默认的PropertyEditor
    4. 添加一个Bean的后置处理器:ApplicationContextAwareProcessor,是一个BeanPostProcessor,用来执行EnvironmentAware、ApplicationEventPublisherAware等回调方法
    5. 添加ignoredDependencyInterface:可以向这个属性中添加一些接口,如果某个类实现了这个接口,并且这个类中的某些set方法在接口中也存在,那么这个set方法在自动注入的时候是不会执行的,比如EnvironmentAware这个接口,如果某个类实现了这个接口,那么就必须实现它的setEnvironment方法,而这是一个set方法,和Spring中的autowire是冲突的,那么Spring在自动注入时是不会调用setEnvironment方法的,而是等到回调Aware接口时再来调用(注意,这个功能仅限于xml的autowire,@Autowired注解是忽略这个属性的)
      1. EnvironmentAware
      2. EmbeddedValueResolverAware
      3. ResourceLoaderAware
      4. ApplicationEventPublisherAware
      5. MessageSourceAware
      6. ApplicationContextAware
      7. 另外其实在构造BeanFactory的时候就已经提前添加了另外三个:
      8. BeanNameAware
      9. BeanClassLoaderAware
      10. BeanFactoryAware
    6. 添加resolvableDependencies:在byType进行依赖注入时,会先从这个属性中根据类型找bean
      1. BeanFactory.class:当前BeanFactory对象
      2. ResourceLoader.class:当前ApplicationContext对象
      3. ApplicationEventPublisher.class:当前ApplicationContext对象
      4. ApplicationContext.class:当前ApplicationContext对象
    7. 添加一个Bean的后置处理器:ApplicationListenerDetector,是一个BeanPostProcessor,用来判断某个Bean是不是ApplicationListener,如果是则把这个Bean添加到ApplicationContext中去,注意一个ApplicationListener只能是单例的
    8. 添加一个Bean的后置处理器:LoadTimeWeaverAwareProcessor,是一个BeanPostProcessor,用来判断某个Bean是不是实现了LoadTimeWeaverAware接口,如果实现了则把ApplicationContext中的loadTimeWeaver回调setLoadTimeWeaver方法设置给该Bean
    9. 添加一些单例bean到单例池:
      1. “environment”:Environment对象
      2. “systemProperties”:System.getProperties()返回的Map对象
      3. “systemEnvironment”:System.getenv()返回的Map对象
  9. postProcessBeanFactory(beanFactory) : 提供给AbstractApplicationContext的子类进行扩展,具体的子类,可以继续向BeanFactory中再添加一些东西
  10. invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor
  11. 此时在BeanFactory中会存在一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor,它也是一个BeanDefinitionRegistryPostProcessor
  12. 第一阶段
  13. 从BeanFactory中找到类型为BeanDefinitionRegistryPostProcessor的beanName,也就是ConfigurationClassPostProcessor, 然后调用BeanFactory的getBean方法得到实例对象
  14. 执行**ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()**方法:
    1. 解析AppConfig类
    2. 扫描得到BeanDefinition并注册
    3. 解析@Import,@Bean等注解得到BeanDefinition并注册
    4. 详细的看另外的笔记,专门分析了ConfigurationClassPostProcessor是如何工作的
    5. 在这里,我们只需要知道在这一步会去得到BeanDefinition,而这些BeanDefinition中可能存在BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,所以执行完ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry()方法后,还需要继续执行其他BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  15. 执行其他BeanDefinitionRegistryPostProcessor的**postProcessBeanDefinitionRegistry()**方法
  16. 执行所有BeanDefinitionRegistryPostProcessor的**postProcessBeanFactory()**方法
  17. 第二阶段
  18. 从BeanFactory中找到类型为BeanFactoryPostProcessor的beanName,而这些BeanFactoryPostProcessor包括了上面的BeanDefinitionRegistryPostProcessor
  19. 执行还没有执行过的BeanFactoryPostProcessor的**postProcessBeanFactory()**方法
  20. 到此,所有的BeanFactoryPostProcessor的逻辑都执行完了,主要做的事情就是得到BeanDefinition并注册到BeanFactory中
  21. registerBeanPostProcessors(beanFactory):因为上面的步骤完成了扫描,这个过程中程序员可能自己定义了一些BeanPostProcessor,在这一步就会把BeanFactory中所有的BeanPostProcessor找出来并实例化得到一个对象,并添加到BeanFactory中去(属性beanPostProcessors),最后再重新添加一个ApplicationListenerDetector对象(之前其实就添加了过,这里是为了把ApplicationListenerDetector移动到最后)
  22. initMessageSource():如果BeanFactory中存在一个叫做"messageSource"的BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的messageSource属性,让ApplicationContext拥有国际化的功能
  23. initApplicationEventMulticaster():如果BeanFactory中存在一个叫做"applicationEventMulticaster"的BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的applicationEventMulticaster属性,让ApplicationContext拥有事件发布的功能
  24. onRefresh():提供给AbstractApplicationContext的子类进行扩展,没用
  25. registerListeners():从BeanFactory中获取ApplicationListener类型的beanName,然后添加到ApplicationContext中的事件广播器applicationEventMulticaster中去,到这一步因为FactoryBean还没有调用getObject()方法生成Bean对象,所以这里要在根据类型找一下ApplicationListener,记录一下对应的beanName
  26. finishBeanFactoryInitialization(beanFactory):完成BeanFactory的初始化,主要就是实例化非懒加载的单例Bean
  27. finishRefresh():BeanFactory的初始化完后,就到了Spring启动的最后一步了
  28. 设置ApplicationContext的lifecycleProcessor,默认情况下设置的是DefaultLifecycleProcessor
  29. 调用lifecycleProcessor的onRefresh()方法,如果是DefaultLifecycleProcessor,那么会获取所有类型为Lifecycle的Bean对象,然后调用它的start()方法,这就是ApplicationContext的生命周期扩展机制
  30. 发布ContextRefreshedEvent事件

BeanFactoryPostProcessor

执行各个BeanDefinitionRegistryPostProcessor流程:

  1. 执行通过ApplicationContext添加进来的BeanDefinitionRegistryPostProcessor的**postProcessBeanDefinitionRegistry()**方法
  2. 执行BeanFactory中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的**postProcessBeanDefinitionRegistry()**方法
  3. 执行BeanFactory中实现了Ordered接口的BeanDefinitionRegistryPostProcessor的**postProcessBeanDefinitionRegistry()**方法
  4. 执行BeanFactory中其他的BeanDefinitionRegistryPostProcessor的**postProcessBeanDefinitionRegistry()**方法
  5. 执行上面所有的BeanDefinitionRegistryPostProcessor的**postProcessBeanFactory()**方法
  6. 执行通过ApplicationContext添加进来的BeanFactoryPostProcessor的**postProcessBeanFactory()**方法
  7. 执行BeanFactory中实现了PriorityOrdered接口的BeanFactoryPostProcessor的**postProcessBeanFactory()**方法
  8. 执行BeanFactory中实现了Ordered接口的BeanFactoryPostProcessor的**postProcessBeanFactory()**方法
  9. 执行BeanFactory中其他的BeanFactoryPostProcessor的**postProcessBeanFactory()**方法

Lifecycle接口

Lifecycle表示的是ApplicationContext的生命周期,可以定义一个SmartLifecycle来监听ApplicationContext的启动和关闭,如下:

@Component
public class FireLifecycle implements SmartLifecycle {

	private boolean isRunning = false;

	@Override
	public void start() {
		System.out.println("启动");
		isRunning = true;
	}

	@Override
	public void stop() {
        // 要触发stop(),要调用context.close(),或者注册关闭钩子(context.registerShutdownHook();)
		System.out.println("停止");
		isRunning = false;
	}

	@Override
	public boolean isRunning() {
		return isRunning;
	}
}

你可能感兴趣的:(#,SSM框架,spring,spring启动,spring源码)