博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot 使用ApplicationListener监听器
阅读量:7120 次
发布时间:2019-06-28

本文共 3250 字,大约阅读时间需要 10 分钟。

hot3.png

使用场景

在一些业务场景中,当Serverlet容器初始化完成、重启、关闭等等一系列动作之后,需要处理一些操作,比如一些数据的加载、初始化缓存、特定任务的注册等等。这个时候我们就可以使用Spring提供的ApplicationListener来进行操作。

原理

ApplicationListener是一个接口,里面只有一个onApplicationEvent方法,方法的参数为ApplicationEvent,ApplicationEvent是个抽象类,顾名思义就是Spring应用的一些Event,ApplicationEvent又有一个抽象子类ApplicationContextEvent,这里用到的就是ApplicationContextEvent的实现类。查看ApplicationContextEvent文档的实现类,有, , , ,这四个都是spring context包中的核心实现:

ApplicationEvent

  |-ApplicationContextEvent
    |-ContextClosedEvent:应用关闭事件
    |-ContextRefreshedEvent:应用刷新事件
    |-ContextStartedEvent:应用开启事件
    |-ContextStoppedEvent:应用停止事件

 

另外:spring boot扩展了两个实现:

    EmbeddedServletContainerInitializedEvent:内嵌Servlet容器初始化事件

    ApplicationReadyEvent:spring Application启动完成事件

用法

本文以在Spring boot下的使用为例来进行说明。首先,需要实现ApplicationListener接口并实现onApplicationEvent方法。把需要处理的操作放在onApplicationEvent中进行处理:

import lombok.extern.slf4j.Slf4j;import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;import org.springframework.boot.context.event.ApplicationReadyEvent;import org.springframework.context.ApplicationEvent;import org.springframework.context.ApplicationListener;import org.springframework.context.event.ContextClosedEvent;import org.springframework.context.event.ContextRefreshedEvent;import org.springframework.context.event.ContextStartedEvent;import org.springframework.context.event.ContextStoppedEvent;/** * Created by dongsilin on 2017/12/18. */@Slf4jpublic class AppApplicationListener implements ApplicationListener {    @Override    public void onApplicationEvent(ApplicationEvent event) {        log.info("+++++++++++++++++++++++++++++++++++++++++++++");        if (event instanceof ContextStartedEvent){            log.info("================:{}", "ContextStartedEvent");        }        if (event instanceof ContextRefreshedEvent){            log.info("================:{}", "ContextRefreshedEvent");        }        if (event instanceof ContextClosedEvent){            log.info("================:{}", "ContextClosedEvent");        }        if (event instanceof ContextStoppedEvent){            log.info("================:{}", "ContextStoppedEvent");        }        if (event instanceof EmbeddedServletContainerInitializedEvent){            log.info("================:{}", "EmbeddedServletContainerInitializedEvent");        }        if (event instanceof ApplicationReadyEvent){            log.info("================:{}", "ApplicationReadyEvent");        }        log.info(">>>>>>>>>>>>>>>>:{}\n", event.getClass().getName());    }}
@SpringBootApplicationpublic class DemoApplication {	public static void main(String[] args) {		SpringApplication.run(DemoApplication.class, args);	}	@Bean	public AppApplicationListener appApplicationListener(){		return new AppApplicationListener();	}}

启动运行结果:

关闭运行结果:

二次调用问题

此处使用Spring boot来进行操作,没有出现二次调用的问题。在使用传统的applicationContext.xml和project-servlet.xml配置中会出现二次调用的问题。主要原因是初始化root容器之后,会初始化project-servlet.xml对应的子容器。我们需要的是只执行一遍即可。那么上面打印父容器的代码用来进行判断排除子容器即可。在业务处理之前添加如下判断:

if(contextRefreshedEvent.getApplicationContext().getParent() != null){            return;}

这样其他容器的初始化就会直接返回,而父容器(Parent为null的容器)启动时将会执行相应的业务操作。

关联知识

在spring中InitializingBean接口也提供了类似的功能,只不过它进行操作的时机是在所有bean都被实例化之后才进行调用。根据不同的业务场景和需求,可选择不同的方案来实现。

转载于:https://my.oschina.net/dslcode/blog/1591523

你可能感兴趣的文章
strust2 和 hibernate的整合------登录的实现
查看>>
关于BOF改进方法的一些introduction
查看>>
20165323 第一周学习总结
查看>>
第二章 例题2-11
查看>>
matlab 车牌分割的算法
查看>>
popoverController简单介绍
查看>>
linux常用命令
查看>>
【重学计算机】计组D1章:计算机系统概论
查看>>
分布式大数据多维分析(OLAP)引擎Apache Kylin安装配置及使用示例【转】
查看>>
Hello Spring(5)ApplicationContext
查看>>
使用zabbix监控mariadb性能状态
查看>>
cacti yum快速部署
查看>>
系统参数递归
查看>>
tomcat详细日志配置
查看>>
Docker学习笔记1
查看>>
字符编码-Unicode等
查看>>
mind map in latex
查看>>
郑捷《机器学习算法原理与编程实践》学习笔记(第四章 推荐系统原理)(三)SVD...
查看>>
log4j整理
查看>>
Oracle Tuning ( instance 级别 ) 01
查看>>