当前位置:   article > 正文

Spring之启动过程源码解析_spring源码启动

spring源码启动

Spring创建Bean,会经过一系列生命周期的流程,而Spring启动,其实就是为了后续创建Bean做一些准备工作,本篇以及下一篇文章都是来详细分析Spring的启动过程。         

目录

一、Spring启动的大致流程

二、Spring加载流程之AnnotatedBeanDefinitionReader

1.Spring程序入口

2.AnnotationConfigApplicationContext的构造函数

3.AnnotatedBeanDefinitionReader的构造函数

4.AnnotationConfigUtils中的registerAnnotationConfigProcessors()

三、refresh()底层原理流程

1.如何理解refresh()?

2.refresh()执行流程拆解分析

3.refresh()执行流程源码注释

四、BeanFactoryPostProcessor

五、BeanDefinitionRegistryPostProcessor

六、Lifecycle的使用


一、Spring启动的大致流程

通常,我们说的Spring启动,其实就是构造ApplicationContext对象以及调用refresh()方法的过程。那么这个过程会涉及到哪些操作呢?以下基于AnnotationConfigApplicationContext来进行说明:

1. 构造一个BeanFactory对象;

2. 构造BeanDefinitionReader,向BeanFactory注册各个注解模式需要的后置处理器;

3. 解析配置类,得到BeanDefinition,并注册到BeanFactory中;

 ① 解析@ComponentScan,此时就会完成扫描

 ② 解析@Import

 ③ 解析@Bean

 ④ ...

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

 4.1. 生成默认的BeanPostProcessor对象,并添加到BeanFactory中:

① AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value 注解;

② CommonAnnotationBeanPostProcessor:处理@Resource、@PostConstruct、 @PreDestroy 注解;

③ ApplicationContextAwareProcessor:处理ApplicationContextAware等回调
 4.2. 找到外部用户自定义的BeanPostProcessor对象(类型为BeanPostProcessor的Bean对象),并添加到BeanFactory中;

5. ApplicationContext支持国际化,需要初始化MessageSource对象;

6. ApplicationContext支持事件机制,还需要初始化ApplicationEventMulticaster对象;

7. 把用户定义的ApplicationListener对象添加到ApplicationContext中,等Spring启动完了就要发布事件了;

8. 创建非懒加载的单例Bean对象,并存在BeanFactory的单例池中;

9. 调用LifecycleBean的start()方法;

10. 发布ContextRefreshedEvent事件;

二、Spring加载流程之AnnotatedBeanDefinitionReader

1.Spring程序入口

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

2.AnnotationConfigApplicationContext的构造函数

AnnotationConfigApplicationContext是Spring的高级容器,有多个构造方法,以下是基于AnnotationConfigApplicationContext(Class<?>... componentClasses)来分析,在这个构造方法中,首先会执行自己的无参构造方法---this(),在this()中会先执行父类GenericApplicationContext的默认构造方法;

  1. public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
  2. /**构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
  3. *这里由于它有父类,所以会先调用父类的构造方法,初始化DefaultListableBeanFactory
  4. *AnnotationConfigApplicationContext容器无参构造器--->父类GenericApplicationContext无参构造器,创建this.beanFactory = new DefaultListableBeanFactory();
  5. */
  6. this();
  7. //注册相关信息
  8. register(componentClasses);
  9. //刷新容器---核心
  10. refresh();
  11. }
  1. public GenericApplicationContext() {
  2. // 初始化一个beanFactory
  3. this.beanFactory = new DefaultListableBeanFactory();
  4. }

这个DefaultListableBeanFactory,非常重要,Spring加载的bean都会放到这个Bean工厂中,
当然GenericApplicationContext的父类AbstractApplicationContext,包括AbstractApplicationContext的父类DefaultResourceLoader都有默认构造方法的;

  1. public AbstractApplicationContext() {
  2. this.resourcePatternResolver = getResourcePatternResolver();
  3. }
  4. public DefaultResourceLoader() {
  5. }

这些提前初始化的属性到后面都会用到,以下是继承关系图:

3.构造AnnotatedBeanDefinitionReader

回到AnnotationConfigApplicationContext(Class<?>... componentClasses)构造方法中的this(),

构造AnnotatedBeanDefinitionReader,主要作用是对BeanFactory进行设置和添加一些基础的PostProcessor(后置处理器),同时可以通过reader进行BeanDefinition的注册;

  1. public AnnotationConfigApplicationContext() {
  2. StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
  3. /** 什么是bean定义 ? BeanDefinition
  4. * 创建一个读取注解的Bean定义读取器,它的register()方法能够将类解析成为一个BeanDefination,然后将BeanDefination对象存到beanDefinationMap中,而beanDefinationMap是在Bean工厂中
  5. * 完成了Spring内部BeanDefinition的注册(主要是后置处理器)
  6. * 额外会创建StandardEnvironment
  7. */
  8. this.reader = new AnnotatedBeanDefinitionReader(this);//this 指的就是DefaultListableBeanFactory
  9. createAnnotatedBeanDefReader.end();
  10. /** 创建BeanDefinition扫描器,可以用来扫描包或者类继而转换为BeanDefinition
  11. * Spring默认的扫描器其实不是这个scanner对象,而是在后面自己又重新new了一个ClassPathBeanDefinitionScanner
  12. * Spring在执行工程后置处理器ConfigurationClassPostProcessor时,去扫描包时会new一个ClassPathBeanDefinitionScanner
  13. * 这里的scanner仅仅是为了程序员可以手动调用AnnotationConfigApplicationContext对象的scan方法
  14. */
  15. this.scanner = new ClassPathBeanDefinitionScanner(this);
  16. }

对于AnnotatedBeanDefinitionReader()构造函数里面的参数registry其实就是DefaultListableBeanFactory;

  1. public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
  2. this(registry, getOrCreateEnvironment(registry));
  3. }
  4. public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
  5. Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
  6. Assert.notNull(environment, "Environment must not be null");
  7. this.registry = registry;
  8. // 解析器,用来解析@Conditional注解的
  9. this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
  10. /** registerAnnotationConfigProcessors,向BeanFactory注册各个注解模式需要的后置处理器
  11. * 根据名字顾名思义就是->注册注解配置的处理器,也就是这个方法里面会注册一些用于处理注解的处理器
  12. */
  13. AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
  14. }

4.AnnotationConfigUtils中的registerAnnotationConfigProcessors()

  1. public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
  2. registerAnnotationConfigProcessors(registry, null);
  3. }
  4. public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
  5. BeanDefinitionRegistry registry, @Nullable Object source) {
  6. // 获取beanFactory也就是DefaultListableBeanFactory
  7. DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
  8. if (beanFactory != null) {
  9. /**
  10. * 设置比较器,它是一个Comparator,可以用来进行排序,比如new ArrayList<>().sort(Comparator),主要能解析@Order@Priority
  11. * 会获取某个对象上的Order注解或者通过实现Ordered接口所定义的值进行排序,在日常开发中可以利用这个类来进行排序
  12. */
  13. if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
  14. beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
  15. }
  16. /**
  17. * 设置依赖注入的候选处理器,用来判断某个Bean能不能用来进行依赖注入
  18. * 可以看到只要不是ContextAnnotationAutowireCandidateResolver类型 直接升级为最强类型
  19. */
  20. if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
  21. beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
  22. }
  23. }
  24. Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
  25. /**注册ConfigurationClassPostProcessor类型的BeanDefinition,ConfigurationClassPostProcessor是一个工厂后置处理器
  26. * 这个后置处理器非常重要,基本上类上面的注解都在这里面判断并解析,Spring的包扫描也在里面完成
  27. */
  28. if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  29. RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
  30. def.setSource(source);
  31. beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
  32. }
  33. /**
  34. * 注册AutowiredAnnotationBeanPostProcessor类型的BeanDefinition
  35. * 处理@Autowired注解的,它是一个bean的后置处理器,在bean的属性注入的时候会用到
  36. */
  37. if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  38. RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
  39. def.setSource(source);
  40. beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
  41. }
  42. /**
  43. * 注册CommonAnnotationBeanPostProcessor类型的BeanDefinition
  44. * 处理一些公共注解的,它是一个bean的后置处理器,可以处理@PostConstruct@PreDestroy还有@Resource
  45. */
  46. // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
  47. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  48. RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
  49. def.setSource(source);
  50. beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
  51. }
  52. // 注册PersistenceAnnotationBeanPostProcessor类型的BeanDefinition
  53. // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
  54. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  55. RootBeanDefinition def = new RootBeanDefinition();
  56. try {
  57. def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
  58. AnnotationConfigUtils.class.getClassLoader()));
  59. }
  60. catch (ClassNotFoundException ex) {
  61. throw new IllegalStateException(
  62. "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
  63. }
  64. def.setSource(source);
  65. beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
  66. }
  67. /**
  68. * 注册EventListenerMethodProcessor类型的BeanDefinition,用来处理@EventListener注解的
  69. * Spring实现事件监听的方式有很多种,其中一种就是在方法上添加@EventListener注解
  70. */
  71. if (
  72. if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
  73. RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
  74. def.setSource(source);
  75. beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
  76. }
  77. // 注册DefaultEventListenerFactory类型的BeanDefinition,用来处理@EventListener注解的
  78. if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
  79. RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
  80. def.setSource(source);
  81. beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
  82. }
  83. return beanDefs;
  84. }

三、refresh()底层原理流程

1.如何理解refresh()?

  1. /**
  2. * Load or refresh the persistent representation of the configuration, which
  3. * might be from Java-based configuration, an XML file, a properties file, a
  4. * relational database schema, or some other format.
  5. * <p>As this is a startup method, it should destroy already created singletons
  6. * if it fails, to avoid dangling resources. In other words, after invocation
  7. * of this method, either all or no singletons at all should be instantiated.
  8. * @throws BeansException if the bean factory could not be initialized
  9. * @throws IllegalStateException if already initialized and multiple refresh
  10. * attempts are not supported
  11. */
  12. void refresh() throws BeansException, IllegalStateException;

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

在Spring的设计中,也提供可以刷新的ApplicationContext和不可以刷新的ApplicationContext, 比如:

AbstractRefreshableApplicationContext extends AbstractApplicationContext

就是可以刷新的;

GenericApplicationContext extends AbstractApplicationContext

就是不可以刷新的。 AnnotationConfigApplicationContext继承的是GenericApplicationContext,所以它是不能刷新的; AnnotationConfigWebApplicationContext继承的是 AbstractRefreshableWebApplicationContext,所以它是可以刷新的,上面说的不能刷新是指不能重复刷新,只能调用一次refresh方法,第二次时会报错。

2.refresh()执行流程拆解分析

2.1. prepareRefresh():

 ① 可以允许子容器设置一些内容到Environment中;

 ② 验证Environment中是否包括了必须要有的属性;

2.2. obtainFreshBeanFactory():进行BeanFactory的refresh,在这里会去调用子类的 refreshBeanFactory方法,具体子类是怎么刷新的得看子类的实现,最后再调用子类的 getBeanFactory方法,重新得到一个BeanFactory;

2.3. prepareBeanFactory(beanFactory):

 ① 设置beanFactory的类加载器,由于创建bean是由Bean工厂来创建,所有如果设置了类加载器,会把类加载器设置到Bean工厂中;

 ② 设置SpringEL表达式解析器:StandardBeanExpressionResolver,用来解析Spring中的表达式,例如: @Value("#{}"); 

 ③ 添加PropertyEditorRegistrar:ResourceEditorRegistrar,属性编辑器注册器,用来注册一些默认的PropertyEditor ;

 ④ 添加一个Bean的后置处理器:ApplicationContextAwareProcessor,是一个BeanPostProcessor,用来执行EnvironmentAware、ApplicationContextAware、ApplicationEventPublisherAware 等回调方法

 ⑤ 添加ignoredDependencyInterface:可以向这个属性中添加一些接口,如果某个类实现了其中的一个或多个接口,并且这个类中的某些set方法在接口中也存在,那么这个set方法在自动注入的 时候是不会执行的,比如EnvironmentAware这个接口,如果某个类实现了这个接口,那就必须实现它的setEnvironment方法,而这是一个set方法,和Spring中的autowire是冲突 的,那么Spring在自动注入时是不会调用setEnvironment方法的,而是等到回调Aware接口时再来调用(注意,这个功能仅限于xml的autowire,@Autowired注解是忽略这个属性的,这些接口有 EnvironmentAware

EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware

MessageSourceAware、ApplicationContextAware

其实在容器启动构造BeanFactory(DefaultListableBeanFactory)的时候,ignoredDependencyInterface就已经提前添加了另外三个,分別是BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

2.4. 添加resolvableDependencies:在byType进行依赖注入时,会先从这个属性中根据类型找bean

① BeanFactory.class:当前BeanFactory对象

② ResourceLoader.class:当前ApplicationContext对象

③ ApplicationEventPublisher.class:当前ApplicationContext对象

④ ApplicationContext.class:当前ApplicationContext对象

2.5. 添加一个Bean的后置处理器:ApplicationListenerDetector,是一个 BeanPostProcessor,用来判断某个Bean是不是ApplicationListener,如果是则把这个 Bean添加到ApplicationContext中去,注意一个ApplicationListener只能是单例的;

2.6. 添加一个Bean的后置处理器:LoadTimeWeaverAwareProcessor,是一个 BeanPostProcessor,用来判断某个Bean是不是实现了LoadTimeWeaverAware接口,如果实现了则把ApplicationContext中的loadTimeWeaver回调setLoadTimeWeaver方法设置给该Bean;

2.7. 添加一些单例bean到单例池:

① "environment":Environment对象

② "systemProperties":System.getSystemProperties()返回的Map对象

③  "systemEnvironment":System.getSystemEnvironment)返回的Map对象

④ "applicationStartup":DefaultApplicationStartup对象

2.8. postProcessBeanFactory(beanFactory) : 提供给AbstractApplicationContext的子类进行扩 展,具体的子类,可以继续向BeanFactory中再添加一些东西;

2.9. invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor,到这一步,在BeanFactory中已经存在一个BeanFactoryPostProcessor: ConfigurationClassPostProcessor,它也是一个BeanDefinitionRegistryPostProcessor

 2.9.1. 执行通过ApplicationContext添加进来的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;

 2.9.2. 执行BeanFactory中实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;

 2.9.3. 执行BeanFactory中实现了Ordered接口的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;

 2.9.4. 执行BeanFactory中其他的BeanDefinitionRegistryPostProcessor的 postProcessBeanDefinitionRegistry()方法 ;

 2.9.5. 执行上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法 ;

 2.9.6. 执行通过ApplicationContext添加进来的BeanFactoryPostProcessor的 postProcessBeanFactory()方法 ;

 2.9.7. 执行BeanFactory中实现了PriorityOrdered接口的BeanFactoryPostProcessor的 postProcessBeanFactory()方法 ;

 2.9.8. 执行BeanFactory中实现了Ordered接口的BeanFactoryPostProcessor的  postProcessBeanFactory()方法 ;

 2.9.9. 执行BeanFactory中其他的BeanFactoryPostProcessor的postProcessBeanFactory()方法;

2.10. registerBeanPostProcessors(beanFactory):因为上面的步骤完成了扫描,这个过程中我们可能自己定义了一些BeanPostProcessor,在这一步就会把BeanFactory中所有的 BeanPostProcessor找出来实例化得到相应的对象,并添加到BeanFactory中去(属性 beanPostProcessors),最后再重新添加一个ApplicationListenerDetector对象(之前其实就添加了过,这里是为了把ApplicationListenerDetector移动到最后);

2.11. initMessageSource():ApplicationContext是支持国际化的,但不是自己完全去实现,而是利用MessageSource去实现的,而MessageSource通常是需要我们自己去定义的,如果BeanFactory中存在一个叫做"messageSource"的 BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的 messageSource属性,让ApplicationContext拥有国际化的功能;

2.12.initApplicationEventMulticaster():初始化事件监听多路广播器,如果BeanFactory中存在一个叫做"applicationEventMulticaster"的BeanDefinition,就会把这个Bean对象创建出来并赋值给ApplicationContext的applicationEventMulticaster属性,如果没有,则默认采用SimpleApplicationEventMulticaster,让ApplicationContext拥有事件发布的功能;

2.13. onRefresh():提供给AbstractApplicationContext的子类进行扩展;

2.14. registerListeners():从BeanFactory中获取ApplicationListener类型的beanName,然后添加 到ApplicationContext中的事件广播器applicationEventMulticaster中去,到这一步因为 FactoryBean还没有调用getObject()方法生成Bean对象,所以这里要在根据类型找一下 ApplicationListener,记录一下对应的beanName;

2.15. finishBeanFactoryInitialization(beanFactory):完成BeanFactory的初始化,主要就是实例化 非懒加载的单例Bean;

2.16. finishRefresh():BeanFactory的初始化完后,就到了Spring启动的最后一步了,

 ① 初始化ApplicationContext的lifecycleProcessor,默认情况下设置的是     DefaultLifecycleProcessor ;

 ② 调用lifecycleProcessor的onRefresh()方法,如果是DefaultLifecycleProcessor,那么会获取所 有类型为Lifecycle的Bean对象,然后调用它的start()方法,这就是ApplicationContext的生命 周期扩展机制;

  1. @Override
  2. public void onRefresh() {
  3. startBeans(true);
  4. }
  5. private void startBeans(boolean autoStartupOnly) {
  6. Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
  7. Map<Integer, LifecycleGroup> phases = new TreeMap<>();
  8. // 按每个Bean的phase进行分组
  9. lifecycleBeans.forEach((beanName, bean) -> {
  10. if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
  11. int phase = getPhase(bean);
  12. phases.computeIfAbsent(
  13. phase,
  14. p -> new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly)
  15. ).add(beanName, bean);
  16. }
  17. });
  18. // 按分组执行start()
  19. if (!phases.isEmpty()) {
  20. phases.values().forEach(LifecycleGroup::start);
  21. }
  22. }
  23. protected Map<String, Lifecycle> getLifecycleBeans() {
  24. ConfigurableListableBeanFactory beanFactory = getBeanFactory();
  25. Map<String, Lifecycle> beans = new LinkedHashMap<>();
  26. //获取beanFactory中所有Lifecycle类型的beanName
  27. String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
  28. for (String beanName : beanNames) {
  29. String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
  30. boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
  31. String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
  32. // 如果所定义的Lifecycle的Bean是单例并且(不是FactoryBean或是Lifecycle类型或是SmartLifecycle类型的)
  33. if ((beanFactory.containsSingleton(beanNameToRegister) &&
  34. (!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
  35. matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
  36. Object bean = beanFactory.getBean(beanNameToCheck);
  37. if (bean != this && bean instanceof Lifecycle) {
  38. beans.put(beanNameToRegister, (Lifecycle) bean);
  39. }
  40. }
  41. }
  42. return beans;
  43. }

③ 发布ContextRefreshedEvent事件;

3.refresh()执行流程源码注释

  1. public void refresh() throws BeansException, IllegalStateException {
  2. synchronized (this.startupShutdownMonitor) {
  3. StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
  4. // 启动前的准备工作
  5. prepareRefresh();
  6. /*
  7. * 由于web项目中并不会先引入DefaultListableBeanFactory,在这里通知子类刷新BeanFactory,例如:AbstractRefreshableApplicationContext
  8. * 而我们是使用new AnnotationConfigApplicationContext()的方式,就是直接返回之前引入的DefaultListableBeanFactory
  9. * Tell the subclass to refresh the internal bean factory.
  10. * 这里会判断能否刷新,并且返回一个BeanFactory
  11. * 对于能进行重复刷新的子容器,刷新不代表完全清空,主要是先执行Bean的销毁,然后重新生成一个BeanFactory,再在接下来的步骤中重新去扫描等等
  12. */
  13. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
  14. // Prepare the bean factory for use in this context.
  15. // 准备BeanFactory
  16. // 1. 设置BeanFactory的类加载器、SpringEL表达式解析器、类型转化注册器
  17. // 2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象
  18. // 3. 记录ignoreDependencyInterface
  19. // 4. 记录ResolvableDependency
  20. // 5. 添加三个单例Bean
  21. prepareBeanFactory(beanFactory);
  22. try {
  23. // Allows post-processing of the bean factory in context subclasses.
  24. // 留的扩展方法,子类来设置一下BeanFactory
  25. postProcessBeanFactory(beanFactory);
  26. StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
  27. // Invoke factory processors registered as beans in the context.
  28. // BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理
  29. // 默认情况下:
  30. // 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition
  31. // 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
  32. // 这里会用ConfigurationClassPostProcessor这个类进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
  33. // 再具体一点就是执行ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry()方法进行扫描
  34. // 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
  35. invokeBeanFactoryPostProcessors(beanFactory); // scanner.scan()
  36. // Register bean processors that intercept bean creation.
  37. // 将扫描到的BeanPostProcessors实例化并排序,并添加到BeanFactory的beanPostProcessors属性中去
  38. registerBeanPostProcessors(beanFactory);
  39. beanPostProcess.end();
  40. // Initialize message source for this context.
  41. // 设置ApplicationContext的MessageSource,可以是用户设置的,或者是DelegatingMessageSource
  42. // ApplicationContext是支持国际化的,但不是自己完全去实现,而是利用MessageSource去实现的,而MessageSource通常是需要我们自己去定义的
  43. initMessageSource();
  44. // Initialize event multicaster for this context.
  45. // 初始化事件监听多路广播器,设置ApplicationContext的applicationEventMulticaster,可以是用户设置的,或者是默认的SimpleApplicationEventMulticaster
  46. initApplicationEventMulticaster();
  47. // Initialize other special beans in specific context subclasses.
  48. // 给子类的模板方法
  49. onRefresh();
  50. // Check for listener beans and register them.
  51. // 把定义的ApplicationListener的Bean对象,设置到ApplicationContext中去,并执行在此之前所发布的事件
  52. registerListeners();
  53. /**
  54. * Instantiate all remaining (non-lazy-init) singletons.
  55. * 创建非懒加载的单例bean,创建bean的时候需要用到BeanPostProcessor,而BeanPostProcessor都是存在于beanPostProcessors中
  56. * 而registerBeanPostProcessors(beanFactory)就是向BeanFactory的beanPostProcessors中添加BeanPostProcessor的对象
  57. */
  58. finishBeanFactoryInitialization(beanFactory);
  59. // Last step: publish corresponding event.
  60. finishRefresh();
  61. }
  62. catch (BeansException ex) {
  63. if (logger.isWarnEnabled()) {
  64. logger.warn("Exception encountered during context initialization - " +
  65. "cancelling refresh attempt: " + ex);
  66. }
  67. // Destroy already created singletons to avoid dangling resources.
  68. destroyBeans();
  69. // Reset 'active' flag.
  70. cancelRefresh(ex);
  71. // Propagate exception to caller.
  72. throw ex;
  73. }
  74. finally {
  75. // Reset common introspection caches in Spring's core, since we
  76. // might not ever need metadata for singleton beans anymore...
  77. resetCommonCaches();
  78. contextRefresh.end();
  79. }
  80. }
  81. }

四、BeanFactoryPostProcessor

BeanPostProcessor表示Bean的后置处理器,是用来对Bean进行加工的,类似的, BeanFactoryPostProcessor理解为BeanFactory的后置处理器,用来用对BeanFactory进行加工的, Spring支持用户自定义BeanFactoryPostProcessor的实现类,来对BeanFactory进行加工,比例如:

  1. @Component
  2. public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
  3. @Override
  4. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
  5. throws BeansException {
  6. BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
  7. beanDefinition.setAutowireCandidate(false);
  8. }
  9. }

以上代码,就利用了BeanFactoryPostProcessor来拿到BeanFactory,然后获取BeanFactory内的某个BeanDefinition对象并进行修改,这一步是发生在Spring启动时,创建单例Bean之前的,所以此时对BeanDefinition就行修改是会生效的。 注意:在ApplicationContext内部有一个核心的DefaultListableBeanFactory,它实现了 ConfigurableListableBeanFactory和BeanDefinitionRegistry接口,所以ApplicationContext和 DefaultListableBeanFactory是可以注册BeanDefinition的,而ConfigurableListableBeanFactory是不能注册BeanDefinition的,只能获取BeanDefinition,对BeanDefinition做修改。

五、BeanDefinitionRegistryPostProcessor

Spring还提供了一个BeanFactoryPostProcessor的子接口: BeanDefinitionRegistryPostProcessor

  1. public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
  2. void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws
  3. BeansException;
  4. }

我们可以看到BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,并新 增了一个方法,注意方法的参数为BeanDefinitionRegistry,如果我们自定义一个类来实现 BeanDefinitionRegistryPostProcessor,那么在postProcessBeanDefinitionRegistry()方法中就可 以注册BeanDefinition了。比如:

  1. @Component
  2. public class MyBeanDefinitionRegistryPostProcessor implements
  3. BeanDefinitionRegistryPostProcessor {
  4. @Override
  5. public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws
  6. BeansException {
  7. AbstractBeanDefinition beanDefinition =
  8. BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
  9. beanDefinition.setBeanClass(User.class);
  10. registry.registerBeanDefinition("user", beanDefinition);
  11. }
  12. @Override
  13. public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
  14. throws BeansException {
  15. BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
  16. beanDefinition.setAutowireCandidate(false);
  17. }
  18. }

六、Lifecycle的使用

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

  1. /**
  2. * Bean有生命周期,对于Spring容器而言也有一个生命周期,如果我们想去监听Spring容器什么时候创建好?有以下做法:
  3. * 1.监听Spring容器发布的这个事件 :publishEvent(new ContextRefreshedEvent(this))
  4. * 2.监听当前Spring容器是否启动完了,如下做法:
  5. */
  6. @Component
  7. //@Scope("prototype")
  8. public class MyLifecycle implements SmartLifecycle {
  9. private boolean isRunning;
  10. /**
  11. * Spring容器启动完了会调用start()
  12. */
  13. @Override
  14. public void start() {
  15. System.out.println("start...");
  16. isRunning=true;
  17. }
  18. /**
  19. * 调start()之前会执行isRunning(),判断当前是不是在运行,如果当前不是处于运行的过程中,才会调start()
  20. * 如果是在运行(true)才能调stop方法
  21. * 要触发stop(),要调用context.close(),或者注册关闭钩子(context.registerShutdownHook())
  22. */
  23. @Override
  24. public void stop() {
  25. System.out.println("stop...");
  26. }
  27. @Override
  28. public boolean isRunning() {
  29. return isRunning;
  30. }
  31. //分组
  32. @Override
  33. public int getPhase() {
  34. return 1;
  35. }
  36. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/609377
推荐阅读
相关标签
  

闽ICP备14008679号