SpringBoot启动过程中涉及到了扩展接口

摘要:
它用于获取与Spring启动相关的对象。当项目启动时,您需要直接调用BeanPostProcessor接口。7.BeanPostProcessor接口用于调用bean初始化方法init方法之前和之后的处理。
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);
    }
}

当然我们也可以用事件监听器中执行这个操作。灵活多变吧

待补充

免责声明:文章转载自《SpringBoot启动过程中涉及到了扩展接口》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇windows批量修改文件后缀名支付宝接口(扫码支付的原理)使用文档说明 支付宝异步通知(notify_url)与return_url下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

根据IP查询所在城市接口(查询用户所在城市)

转自:https://blog.csdn.net/liona_koukou/article/details/75646313 最近项目有用到定位用户客户端打开页面时所在的城市的需求,找到如下接口,做个记录 文章为转载 设计蜂巢IP地址查询接口:http://www.hujuntao.com/api/ip/ip.php 腾讯IP地址查询接口:http:/...

js 接口并发问题

最近听到一个词叫"并发",其实在工作中很多这种处理的场景只是没有并发这种概念,今天总结一下 。 假设场景: 一个普通查询页面,需要刚进页面就同时调用4个接口,只有全部接口都调用完成才能让用户操作这时候怎么办? 首先 es6 可以使用 Promise.all() var a = new Promise((resolve,reject)=>{setTim...

ogg初始化抽取的快速配置方法一: 将存量数据落地为标准trail

源端抽取进程 此进程与普通的select操作类似,只是从某个时间点开始读取表里的数据。 exinit.prm extract exinit userid ogg, password ogg reportcount every 1 miniutes rate extfile ./dirdat/ei, MEGABYTES 2000 table schema.X...

swift3.0 coreData的使用-日记本demo

效果 需求分析 基于官方MasterDetail模板,官方写了很多复杂的coredata逻辑,在此基础上快速开发简单的日记本程序。 - 主要功能:增、删、改、查 - 界面用默认的界面,将detail页面改为`UITextView`可编辑 - 主页面进行 增、删、查操作 - 子页面进行 删、改、查操作 需求很简单,官方模板还添加了按时间排序的操作 创建工...

JAVA android 关于全局监听器

全局监听器 其实只是把每个创建的监听器添加入List里 当SDK里调用一次的时候 遍历所有的监听器 执行每个监听器的这个方法就行了 1.首先写一个监听器的接口 public interface testSDKListener { public void test(String str); } 2.写这个监听器的实现方法 publ...

java~jackson实现接口的反序列化

jackson是springboot中集成的序列化方式,是默认的json序列化方式,当然你可以使用其它的序列化工具代替它,不过今天我们还是说一下它,使用jackson进行序列化一个类,然后再把它的JSON字符反序列化为它的接口对象。 现实 这种方式默认是不行的,因为接口不能被自动实例化 使用redisTelmplete时,如果使用objectMapper...