1.可扩展的接口启动调用顺序图
org.springframework.beans.factory.xxx
org.springframework.boot.xxx
org.springframework.context.xxx
- ApplicationContextInitializer.initialize
- AbstractApplicationContext.refresh
- BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry
- BeanDefinitionRegistryPostProcessor.postProcessBeanFactory
- InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
- SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors
- MergedBeanDefinitionPostProcessor.postProcessorMergedBeanDefinition
- InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
- SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
- BeanFactoryAware.setBeanFactory
- InstantiationAwareBeanPostProcessor.postProcessPropertyValues
- ApplicationContextAwareProcessor.invokeAwareInterfaces
- BeanNameAware.setBeanName
- InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization
- @PostConstruct
- InitiallzingBean.afterPropertiesSet
- InstantiationAwareBeanPostProcessor.postProcessAfterInitialization
- FactoryBean.getObject
- SmartInitilallzingSingleton.afterSingletonInstantiated
- CommondLineRunner.run
- DisposableBean.destry
2.ApplicationContextInitializer
org.springframework.context.ApplicationContextInitializer
这是整个spring容器在刷新之前初始化ConfigurableApplicationContext
的回调接口,简单来说,就是在容器刷新之前调用此类的initialize方法。这个点允许被用户自己扩展。用户可以在整个spring容器还没被初始化之前做一些事情。
可以想到的场景可能为,在最开始激活一些配置
,或者利用这时候class还没被类加载器加载的时机,进行动态字节码注入
等操作。
因为这时候spring容器还没被初始化,所以想要自己的扩展的生效,有以下三种方式:
- 在启动类中用
springApplication.addInitializers(new TestApplicationContextInitializer())
语句加入 - 配置文件配置
context.initializer.classes=com.example.demo.TestApplicationContextInitializer
- Spring SPI扩展,在spring.factories中加入
org.springframework.context.ApplicationContextInitializer=com.example.demo.TestApplicationContextInitializer
3.BeanDefinitionRegistryPostProcessor
org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor
这个接口在读取项目中的beanDefinition之后执行,提供一个补充的扩展点
使用场景:你可以在这里动态注册自己的beanDefinition,可以加载classpath之外的bean
4.BeanFactoryPostProcessor
org.springframework.beans.factory.config.BeanFactoryPostProcessor
这个接口是beanFactory的扩展接口,调用时机在spring在读取beanDefinition信息之后,实例化bean之前。
在这个时机,用户可以通过实现这个扩展接口来自行处理一些东西,比如修改已经注册的beanDefinition的元信息
。
5.InstantiationAwareBeanPostProcessor
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
继承了BeanPostProcessor
, 而BeanPostProcessor
只在bean的初始化阶段进行扩展, 而InstantiationAwareBeanPostProcessor
接口则在初始化阶段, 实例化阶段和属性注入阶段
- postProcessBeforeInstantiation: 实例化bean之前,相当于new这个bean之前
- postProcessAfterInstantiation: 实例化bean之后, 相当与new这个bean之后
- postProcessPropertyValues: bean 已经实例化以后, 在属性注入阶段触发, @Autowired和@Resource基于此方法
- postProcessBeforeInitialization: 初始化bean之前, 相当于把bean注入spring上下文之前
- postProcessAfterInitialization: 初始化bean之后, 相当于把bean注入spring上下文之后
写中间件和业务中,都能利用这个特性。比如对实现了某一类接口的bean在各个生命期间进行收集,或者对某个类型的bean进行统一的设值等等。
6.SmartInstantiationAwareBeanPostProcessor
org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor
- predictBeanType: 该触发点发生在postProcessBeforeInstantiation之前, 这个方法用于预测Bean的类型, 返回第一个预测成功的Class类型, 如果不能预测返回null。当你调用BeanFactory.getType(name)时当通过bean的名字无法得到bean类型信息时就调用该回调方法来决定类型信息。
- determineCandidateConstructors: 该触发点发生在postProcessBeforeInstantiation之后, 用于确定bean的构造函数, 返回的是bean的所以构造函数列表, 可以通过此方法自定义选择对应的构造器来实例化bean
- getEarlyBeanReference: 该触发点发生在postProcessAfterInstantiation之后, 当有循环依赖的场景,当bean实例化好之后,为了防止有循环依赖,会提前暴露回调方法,用于bean实例化的后置处理。这个方法就是在提前暴露的回调方法中触发。
7.BeanFactoryAware
org.springframework.beans.factory.BeanFactoryAware
发生在bean的实例化之后,注入属性之前,也就是Setter之前。这个类的扩展点方法为setBeanFactory,可以拿到BeanFactory这个属性。
可以在bean实例化之后, 初始化之前, 拿到beanFactory, 然后对bean进行特殊化的定制, 或者将beanFactory拿到进行缓存, 日后使用。
8.ApplicationContextAwareProcessor
org.springframework.context.support.ApplicationContextAwareProcessor
6个扩展点: EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware, ApplicationStartupAware
9.BeanNameAware
org.springframework.beans.factory.BeanNameAware
触发点为bean的初始化之前, postProcessBeforeInitialization
方法之前, 可以通过在初始化bean之前拿到spring容器中注册的的beanName, 修改beanName。
10.@PostConstruct
javax.annotation.PostConstruct
触发点是在postProcessBeforeInitialization之后,InitializingBean.afterPropertiesSet之前。
11.InitializingBean
org.springframework.beans.factory.InitializingBean
初始化bean, 在方法postProcessAfterInitialization
之前实现。
进行系统启动的时候一些业务指标的初始化工作
12.FactoryBean
org.springframework.beans.factory.FactoryBean
工厂Bean, Spring提供了70多个实现, 隐藏了复杂的bean的细节, 给上层提供了便利
可以通过这个类, 实例化bean作为一个代理, 比如为该对象的所以方法做一个拦截, 输出一个日志信息。
13.SmartInitializingSingleton
org.springframework.beans.factory.SmartInitializingSingleton
- afterSingletonsInstantiated: 在spring容器管理的所有单例对象(非懒加载对象)初始化完成之后调用的回调接口。在
postProcessAfterInitialization
之后执行。
可以对于所有单例对象初始化后, 做出一些业务处理
14.CommandLineRunner
org.springframework.boot.CommandLineRunner
run方法在触发时机为整个项目启动完毕后,自动执行。如果有多个CommandLineRunner,可以利用@Order来进行排序。
15.DisposableBean
org.springframework.beans.factory.DisposableBean
- destroy: 对象销毁时执行。
16.ApplicationListener
org.springframework.context.ApplicationListener
可以监控某个事件, spring内部有内置事件, 可以利用内置事件的监听器达到和前面一些触发点大致相同的事情。
- ContextRefreshedEvent: ApplicationContext 被初始化或刷新时,该事件被发布。这也可以在ConfigurableApplicationContext接口中使用 refresh()方法来发生。
- ContextStartedEvent: ConfigurableApplicationContext.started()启动ApplicationContext, 发布事件。
- ContextStoppedEvent: ConfigurableApplicationContext.stopped()停止ApplicationContext, 发布事件。
- ContextClosedEvent: ConfigurableApplicationContext.closed()关闭ApplicationContext, 发布事件。
- RequestHandledEvent: web-specific 事件, 告诉所有Bean Http 请求已经被服务。只能应用于使用DispatcherServlet的Web应用。当Spring处理用户请求结束后,系统会自动触发该事件。