画布 1
Spring的扩展点
  基础组件
    SingletonBeanRegistry
    BeanDefinitionRegistry
      BeanDefinition
        属性值
        构造函数参数
    BeanFactory
      getBean
      AbstractAutowireCapableBeanFactory.doCreateBean
        构造器
        fieldInjection
    Context
      applicationContext.publishEvent(new MyEvent(this)); // 这行代码执行完会立即被监听到
    Bean
      生命周期
        Define
        instantiation
        initialization
          所谓的初始化就是除构造器注入以外的所有注入，以及 afsterPropertiesSet/init-method
    ResourceLoader
      通过 InputStream 把配置解析成property，产生了大量的 BeanDefinition
  后处理器（在基础组件的主方法执行完毕后执行）
    BeanDefinitionRegistryPostProcessor
      postProcessBeanDefinitionRegistry()
        这个方法被调用的时候, 所有的BeanDefinition已经被加载了, 但是所有的Bean还没被创建.
    BeanFactoryPostProcessor
      postProcessBeanFactory()
        Modify the application context's internal bean factory after its standard initialization. All bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for overriding or adding properties even to eager-initializing beans.
这个方法被调用的时候，bean factory 已经Initialization 完了, 所有的BeanDefinition have been loaded, but no beans will have been instantiated yet. 也就是说, 通过它我们可以在实例化任何Bean之前, 做各种操作, 甚至读取并修改BeanDefinition(bean定义的元数据).
    BeanPostProcessor
      InstantiationAwareBeanPostProcessor.postProcessProperties 注入 autowired
      setXXXAware 这个方法早于 postProcessBeforeInitialization
      postProcessBeforeInitialization
        在目标 bean 被初始化以前应用这个 BeanPostProcessor。
返回 bean 可以是一个代理而不是目标 bean，它显式地禁用目标 bean 的 instantiation。
所以这个地方只要返回 non-null，就会对 bean 创建流程产生短路效应。
唯一可以进一步处理的只有被配置的 BeanPostProcessor 的 postProcessAfterInitialization 回调函数。
          @PostConstruct
            It is guaranteed that when a given bean's @PostConstruct gets called, that all of its @Resource fields will have been injected. If any of those injections are themselves beans with their own @Resource and @PostConstruct, then those will have already been called. In other words, by the time any given @PostConstruct is called, it is guaranteed that all of its dependencies have been fully initialized.
            Constructor >> @Autowired/@Resource@Inject(populateBean 阶段) >> @PostConstruct（Initialization 阶段的第一前置阶段，postProcessBeforeInitialization）
      afterPropertiesSet
        来自 InitializingBean 这种 bean 可以感知自己的初始化周期的各个阶段的钩子
      xml init-method 完全与 spring 框架在 java 层面解耦，但 afterPropertiesSet 设值失败后流程会被阻断，这里也跑不到。
      postProcessAfterInitialization
        在 bean 被构造器或者工厂方法初始化以后，在 property population 发生以前，在这个地方可以完美地实现自定义的 field 注入-这个方法在 autowire 之前起作用。
返回 true 说明了此 bean 的属性应该被 set。而返回 false 则会导致 bean 的 property population 被 skipped，还会导致其他的任何后续的 InstantiationAwareBeanPostProcessor 实例被调用。
真正的最后方法。
      8 @Predestroy
      9 destoryMethod
      常见子类
        InstantiationAwareBeanPostProcessor
          postProcessBeforeInstantiation 实例化前扩展
            ProxyCreator 可以生成一个前代理的机会
          postProcessAfterInstantiation 实例化后扩展
            在这里返回 false 可以阻断剩下的注入流程，进入完全自定义的流程
          postProcessProperties 依赖注入前扩展
            对 fieldInjection 尤其重要
        MergedBeanDefinitionPostProcessor
          postProcessMergedBeanDefinition 实例化后针对BeanDefinition的扩展
        SmartInstantiationAwareBeanPostProcessor
          determineCandidateConstructors
      被创建的 bean 里实现的方法
      bean 里实现的方法
      这个流程都是 beanFactory 的 doCreateBean 里的 initializeBean 的流程
  aware 组件
    BeanFactoryAware
    ApplicationContextAware
    ResourceLoaderAware
    ServletContextAware
  ApplicationListener
    public void onApplicationEvent(ApplicationEvent event)
  ApplicationEvent
    extends ApplicationEvent
      ApplicationStartedEvent
        spring boot启动开始时执行的事件。这是 Spring Boot 的扩展事件。
      ApplicationEnvironmentPreparedEvent
        spring boot 对应Enviroment已经准备完毕，但此时上下文context还没有创建。这是 Spring Boot 的扩展事件。
      ContextStartedEvent
        Published when the ApplicationContext is started by using the start() method on the ConfigurableApplicationContext interface. Here, “started” means that all Lifecycle beans receive an explicit start signal. Typically, this signal is used to restart beans after an explicit stop, but it may also be used to start components that have not been configured for autostart (for example, components that have not already started on initialization).
当上下文调用开始方法（比如加载一些未被正确加载的 bean）的时候，就会发出这个 event，这个 event 的顺序理论上应该在 ContextRefreshedEvent 之前。
      ContextRefreshedEvent
        Published when the ApplicationContext is initialized or refreshed (for example, by using the refresh() method on the ConfigurableApplicationContext interface). Here, “initialized” means that all beans are loaded, post-processor beans are detected and activated, singletons are pre-instantiated, and the ApplicationContext object is ready for use. As long as the context has not been closed, a refresh can be triggered multiple times, provided that the chosen ApplicationContext actually supports such “hot” refreshes. For example, XmlWebApplicationContext supports hot refreshes, but GenericApplicationContext does not.
这个方法在全生命周期里可以被调用多次，每次被调用的时候，bean 已经被 load 了，且已经准备好被 instantiated 了-还不到 initialization。
这时候上下文还称不上 ready，但 bean 的 definition 已经不会漏了。
      ApplicationFailedEvent
        spring boot启动异常时执行事件。
      ApplicationReadyEvent
        应用可以请求，意味着端口开始监听执行。这是 Spring Boot 的扩展事件。
      CommandLineRunner
      RequestHandledEvent
        请求完成调用（注意可能会调用多次 ）
      ContextStoppedEvent
        Published when the ApplicationContext is stopped by using the stop() method on the ConfigurableApplicationContext interface. Here, “stopped” means that all Lifecycle beans receive an explicit stop signal. A stopped context may be restarted through a start() call.
      ContextClosedEvent
        Published when the ApplicationContext is being closed by using the close() method on the ConfigurableApplicationContext interface or via a JVM shutdown hook. Here, "closed" means that all singleton beans will be destroyed. Once the context is closed, it reaches its end of life and cannot be refreshed or restarted.
  setXXX