SpringApplicationRunListener接口
1、ApplicationListener接口 是ApplicationContext的事件监听器 2、EnvironmentPostProcessor接口 上下文环境后置处理器,事件中调用
3、PropertySourceLoader接口 自定义配置文件加载器,自己解析配置文件属性 4、ApplicationContextInitializer接口 上下文初始化器
5、BeanFactoryPostProcessor接口 对BeanFactory操作了后置处理器 6、Aware接口及其子接口 会在refreshContext()方法中实例化所有bean实例,调用Aware子接口的接口方法。用来获取Spring启动时相关的对象,在项目启动后需要用到时直接调用 7、BeanPostProcessor接口 用于bean初始化方法init-method调用前后进行处理。
8、ApplicationRunner和CommandLineRunner接口
上面
ApplicationListener、ApplicationContextInitializer、BeanFactoryPostProcessor、BeanPostProcessor接口是属于Spring框架原有的
EnvironmentPostProcessor、PropertySourceLoader、ApplicationRunner、SpringApplicationRunListener接口是SpringBoot新加的扩展接口
SpringApplicationRunListener接口
SpringBoot中的事件广播是通过监听器SpringApplicationRunListener接口实现类EventPublishingRunListener来进行事件分发从而调用ApplicationListener监听器的
所以我们可以配置自定义的springboot的监听器
配置在META-INF/spring.factories文件中配置
# Run Listeners org.springframework.boot.SpringApplicationRunListener= org.springframework.boot.context.event.EventPublishingRunListener
1、ApplicationListener接口
是Spring应用生命周期各个阶段的事件监听器,可以在任意一个阶段触发我们想要执行的操作
负责在每个阶段做做对应处理
比如
ApplicationEnvironmentPreparedEvent环境准备完成事件中加载配置文件属性到数据源中
自定义监听器配置也是配置在META-INF/spring.factories文件中
# Application Listeners org.springframework.context.ApplicationListener= org.springframework.boot.ClearCachesApplicationListener, org.springframework.boot.builder.ParentContextCloserApplicationListener
2、EnvironmentPostProcessor接口
上下文环境后置处理器。ApplicationEnvironmentPreparedEvent事件中调用 初始化systemProperties,systemEnvironment属性源之后的处理(servletConfigInitParams,servletContextInitParams这两个属性源未初始化) 比如 ConfigFileApplicationListener.postProcessEnvironment() 用于加载配置文件属性{.xml ,.properties,.yml,.yaml后缀的文件}到系统属性源中 将配置文件读取后添加到属性源中 propertySources.add(new OriginTrackedMapPropertySource(name + documentNumber, loaded.get(i)));
这个自定义配置也是配置在META-INF/spring.factories文件中
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=
3、PropertySourceLoader 接口
自定义配置文件加载器,自己解析配置文件属性, 比如解析.json后缀的配置文件属性到系统中 参考链接:https://blog.csdn.net/catoop/article/details/71157986
配置在META-INF/spring.factories文件中配置方式
# PropertySource Loaders org.springframework.boot.env.PropertySourceLoader= org.springframework.boot.env.PropertiesPropertySourceLoader, org.springframework.boot.env.YamlPropertySourceLoader
4、ApplicationContextInitializer 接口
在springBoot启动时prepareContext() 准备上下文时调用这些接口对applicationContext做一些初始化操作。
调用时间
ApplicationEnvironmentPreparedEvent事件上下文环境准备好之后
ApplicationPreparedEvent事件之前调用
比如
ContextIdApplicationContextInitializer初始化器,为上下文生成contextId上下文id
ConfigurationWarningsApplicationContextInitializer
增加BeanFactory工厂的后置处理器context.addBeanFactoryPostProcessor,用来报告启动过程中配置错误的警告信息postProcessBeanDefinitionRegistry()方法中处理
配置在META-INF/spring.factories文件中配置方式
# Application Context Initializers org.springframework.context.ApplicationContextInitializer= org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer, org.springframework.boot.context.ContextIdApplicationContextInitializer
5、BeanFactoryPostProcessor接口
子接口:BeanDefinitionRegistryPostProcessor,也可以实现子接口对beanFactory进行操作。 对BeanFactory进行操作的后置处理器
总的来说:可以通过BeanDefinitionRegistryPostProcessor接口方法来进行自定义bean注册(也可以操作beanFactory做相应操作)
触发时机:refreshContext(context)==》5.4 invokeBeanFactoryPostProcessors(beanFactory)
可以在初始化bean之前将我们自定义的BeanFactoryPostProcessor实现类注册到BeanFactory中, BeanDefinitionRegistryPostProcessor接口实现类,可以在获取自定义bean定义之前将我们自定义的Bean定义注册到BeanFactory中 Spring对我们自定义Bean的解析也是通过BeanDefinitionRegistryPostProcessor接口 实现类ConfigurationClassPostProcessor来进行扫描和注册bean定义 执行过程是: 先将ApplicationContext的beanFactoryPostProcessors列表转换成 BeanDefinitionRegistryPostProcessor(registryProcessors 注册处理器) 和BeanFactoryPostProcessor(regularPostProcessors规则处理器) 首先会执行 registryProcessors 注册处理器的postProcessBeanDefinitionRegistry(registry)方法进行自定义bean定义的注册 第一次执行注册 会获取BeanFactory中内置的BeanDefinitionRegistryPostProcessor接口实现类,并且这个类要实现PriorityOrdered接口==》ConfigurationClassPostProcessor 会调用ConfigurationClassPostProcessor类的注册方法扫描和注册所有bean定义。 第二次执行注册: 会获取BeanFactory中扫描后获取的BeanDefinitionRegistryPostProcessor接口实现类,并且这个类要实现Ordered接口 调用注册方法 第三次执行注册: 一样获取BeanDefinitionRegistryPostProcessor接口实现,除了上面之外的实现类进行执行注册 比如mybatis相关的bean注册就是在第三次进行注册(MapperScannerConfigurer)
当执行完注册操作后,会将上面的BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor接口实现类
调用接口方法postProcessor.postProcessBeanFactory(beanFactory),beanFactory的后置操作
BeanFactoryPostProcessor或者BeanDefinitionRegistryPostProcessor自定义实现类可以在这个被调用之前注册
也就是refreshContext(context);刷新上下文之前
可以在ApplicationPreparedEvent事件触发时调用ApplicationContext.addBeanFactoryPostProcessor()方法添加到
beanFactoryPostProcessors列表中
当然也可以在这个事件之前进行添加。
6、Aware接口及其子接口
实现Aware接口的接口有很多个
触发时机:refreshContext(context)==》6.0、finishBeanFactoryInitialization(beanFactory)
按照调用地方不同区分:
6.1
BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
上面这三个接口是在
AbstractAutowireCapableBeanFactory的 initializeBean(beanName, exposedObject, mbd);方法invokeAwareMethods(beanName, bean);方法会处理
6.2
ApplicationContextAwareProcessor后置处理器中处理实现
EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,
ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware这些接口的Bean的接口方法调用
6.3WebApplicationContextServletContextAwareProcessor后置处理器中处理
实现了ServletContextAware接口的bean
7、BeanPostProcessor接口
相当于bean初始化方法调用前后的拦截器
会在Bean的初始化方法init-method调用前后进行处理
BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName) 初始化前调用
BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName) 初始化后调用
8、ApplicationRunner和CommandLineRunner接口
是在ApplicationStartedEvent事件之后,触发ApplicationReadyEvent事件之前调用
用于执行启动后的操作。
比如我自定义的@EventBusListener注解到bean上,我要在所有bean初始化后获取到这个bean列表注册到我的事件中心,用于单机应用的异步事件订阅发布执行
@Component public class MyApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { EventBusCenter eventBusCenter = SpringContextUtils.getBean(EventBusCenter.class); // 获取所有带有 @EventBusListener 的 bean,将他们注册为监听者 Map<String, Object> beansWithAnnotation = SpringContextUtils.getApplicationContext().getBeansWithAnnotation(EventBusListener.class); List<Object> listeners = beansWithAnnotation.entrySet().stream().map(Map.Entry::getValue).collect(Collectors.toList()); eventBusCenter.registry(listeners); } }
当然我们也可以用事件监听器中执行这个操作。灵活多变吧
待补充