Java Spring 自定义事件监听
ApplicationContext 事件
定义一个context的起动监听事件
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent; public class EventStart implements ApplicationListener<ContextStartedEvent>{ @Override
public void onApplicationEvent(ContextStartedEvent arg0) {
System.out.println("上下文 开始 事件");
}
}
要定义一个事件监听,首先你得有一个事件,ContextStartedEvent 是一个固定的、具体的事件,Java spring自带的,通过实现
ApplicationListener<ContextStartedEvent >
就可以监控这个事件了
ContextStartedEvent 的定义
@SuppressWarnings("serial")
public class ContextStartedEvent extends ApplicationContextEvent {
/**
* Create a new ContextStartedEvent.
* @param source the {@code ApplicationContext} that has been started
* (must not be {@code null})
*/
public ContextStartedEvent(ApplicationContext source) {
super(source);
}
}
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent; public class EventStop implements ApplicationListener<ContextStoppedEvent> { @Override
public void onApplicationEvent(ContextStoppedEvent arg0) {
System.out.println("上下文 停止 事件");
}
}
主方法
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("b.xml");
context.start();
Dept dept = (Dept)context.getBean("dept");
dept.getLeader();
context.stop();
context.registerShutdownHook();
b.xml
<bean id="eventStart" class="test4.EventStart"></bean>
<bean id="eventStop" class="test4.EventStop"></bean>
输出
初始化 bean.洪七公
初始化 bean.null
家
我
上下文 开始 事件
部门领导洪七公
上下文 停止 事件
销毁 bean.null
销毁 bean.洪七公
为什么主方法中一调用 start 方法,监听事件就可以自己被调用 呢
start方法真正执行的是AbstractApplicationContext的start方法,在方法里,除了真正start要处理的内容外,还额外加了事件处理,
@Override
public void start() {
getLifecycleProcessor().start();
publishEvent(new ContextStartedEvent(this));
}
所加的事件就是ContextStartedEvent事件,在将实例了ApplicationListener<ContextStartedEvent>的bean通过xml注册到spring容器中时,容器自动调用了该bean的onApplicationEvent方法
自定义事件
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Work extends ApplicationEvent{
private static final long serialVersionUID = 1L;
private Person ps;
public void setPs(Person ps) {
this.ps = ps;
}
public Work(Object source) {
super(source);
}
public void doWorking() {
String name = this.ps.getName();
System.out.println(name + " 今天没有完成100张图片制作,并且听到这个任务时,情绪时而激动,时而低落");
}
}
//该类要注册到spring容器,然后容器会自动调用实现ApplicationListener接口的类的onApplicationEvent方法
public class WorkListener implements ApplicationListener<Work>{ @Override
public void onApplicationEvent(Work event) {
// TODO Auto-generated method stub
System.out.println("摄像头记录到:");
event.doWorking();
}
}
public class Sleep extends ApplicationEvent{
private Person ps;
public void setPs(Person ps) {
this.ps = ps;
}
private static final long serialVersionUID = 2L;
public Sleep(Object source) {
super(source);
}
public void doSleeping() {
String name = this.ps.getName();
System.out.println(name + " 开始休息了");
}
}
//该类要注册到spring容器,然后容器会自动调用实现ApplicationListener接口的类的onApplicationEvent方法
public class SleepListener implements ApplicationListener<Sleep> { @Override
public void onApplicationEvent(Sleep event) {
System.out.println("摄像头记录到:");
event.doSleeping();
}
}
public class Report implements ApplicationEventPublisherAware{
private ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
public void work() {
System.out.println("开始小明的工作报告");
Work work = new Work(this);
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("d.xml");
Person xm = (Person)context.getBean("xiaoming");
work.setPs(xm);
this.publisher.publishEvent(work);
}
public void sleep() {
System.out.println("开始小明的睡眠报告");
Sleep sl = new Sleep(this);
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("d.xml");
Person xm = (Person)context.getBean("xiaoming");
sl.setPs(xm);
this.publisher.publishEvent(sl);
}
}
<bean name="xiaoming" class="test6.Person">
<property name="name" value="小明"></property>
</bean> <bean id="wkReport" class="test6.Report"></bean>
<bean id="wkMonitor" class="test6.WorkListener"></bean>
<bean id="slMonitor" class="test6.SleepListener"></bean>
public class Main {
public static void main(String[] args) {
ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("d.xml");
Report rp = (Report)context.getBean("wkReport");
rp.work();
rp.sleep();
context.close();
}
}
输出
开始小明的工作报告
摄像头记录到:
小明 今天没有完成100张图片制作,并且听到这个任务时,情绪时而激动,时而低落
开始小明的睡眠报告
摄像头记录到:
小明 开始休息了
事件本身,Work,Sleep不需要注册到sping容器中。
想要让
rp.work();rp.sleep();
工作,睡觉这样的方法/行为,可以被监控,除了这些方法本身要处理的内容外,
还需要为这个方法定义一个具体的事件类(此例中是Work,Sleep,这些具体的事件类不需要注册到spring容器,因为他们在工作、睡觉这些方法中已经被调用了),
然后将对应的事件类添加到ApplicationEventPublisher事件处理的逻辑中;
在我们调用 工作、睡觉这些方法时,就会触发事件处理逻辑,
spring容器会自动检测哪些bean实现了与之相对应的ApplicationListener监听类,然后调用其onApplicationEvent方法
Java Spring 自定义事件监听的更多相关文章
- Spring之事件监听(观察者模型)
目录 Spring事件监听 一.事件监听案例 1.事件类 2.事件监听类 3.事件发布者 4.配置文件中注册 5.测试 二.Spring中事件监听分析 1. Spring中事件监听的结构 2. 核心角 ...
- Spring的事件监听机制
最近公司在重构广告系统,其中核心的打包功能由广告系统调用,即对apk打包的调用和打包完成之后的回调,需要提供相应的接口给广告系统.因此,为了将apk打包的核心流程和对接广告系统的业务解耦,利用了spr ...
- [问题贴]mui.openWindow+自定义事件监听操作让alert()执行两次
仔细看,Alert函数执行了两次 共两个页面:index.html和detail.html, detail.html为按钮设置了自定义事件监听(newsId),触发alert. 在index.html ...
- 十一、Spring之事件监听
Spring之事件监听 ApplicationListener ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成Applica ...
- Spring的事件监听ApplicationListener
ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件机制. 如果容器中存在Applica ...
- Java中的事件监听机制
鼠标事件监听机制的三个方面: 1.事件源对象: 事件源对象就是能够产生动作的对象.在Java语言中所有的容器组件和元素组件都是事件监听中的事件源对象.Java中根据事件的动作来区分不同的事件源对象,动 ...
- java Gui编程 事件监听机制
1. GUI编程引言 以前的学习当中,我们都使用的是命令交互方式: 例如:在DOS命令行中通过javac java命令启动程序. 软件的交互的方式: 1. 命令交互方式 图书管理系统 ...
- Java界面编程—事件监听机制
组件首先要先注册事件处理器,当用户单击组件.移动鼠标或者敲击键盘时都会产生事件(Event),一旦有时间发生,应用程序就会做出对该事件的响应,这些组件就是事件源(Event source). 接受.解 ...
- Java 中的事件监听机制
看项目代码时遇到了好多事件监听机制相关的代码.现学习一下: java事件机制包含三个部分:事件.事件监听器.事件源. 1.事件:继承自java.util.EventObject类,开发人员自己定义. ...
随机推荐
- vivo 全球商城:商品系统架构设计与实践
一.前言 随着用户量级的快速增长,vivo官方商城v1.0的单体架构逐渐暴露出弊端:模块愈发臃肿.开发效率低下.性能出现瓶颈.系统维护困难. 从2017年开始启动的v2.0架构升级,基于业务模块进行垂 ...
- 【java+selenium3】元素的扩展操作(二)
1.判断当前元素是否可显示 isDisplay(); //判断元素是否可见 boolean a= driver.findElement(By.id("xxx")).isDispla ...
- idea连接数据库时区错误
错误界面 IDEA连接mysql,地址,用户名,密码,数据库名,全都配置好了,点测试连接,咔!不成功! 界面是这样的, 翻译过来就是:服务器返回无效时区.进入"高级"选项卡,手动设 ...
- webpack 配置devServer 服务器
webpack 配置devServer 服务器 /** * loader: 1. 下载 2. 使用(配置) * plugins:1. 下载 2. 引入 3.使用 */ // 用来拼接绝对路径的方法 c ...
- Apache Kyuubi 在 T3 出行的深度实践
支撑了80%的离线作业,日作业量在1W+ 大多数场景比 Hive 性能提升了3-6倍 多租户.并发的场景更加高效稳定 T3出行是一家基于车联网驱动的智慧出行平台,拥有海量且丰富的数据源.因为车联网数据 ...
- 1组-Alpha冲刺-3/6
一.基本情况 队名:震震带着六菜鸟 组长博客:https://www.cnblogs.com/Klein-Wang/p/15544334.html 小组人数:7人 二.冲刺概况汇报 王业震 过去两天完 ...
- [bzoj1071]组队
题目即要求$Ah+Bv<=C+Aminh+Bminv$,如果同时枚举minh和minv,那么即要求$minh\le h$,$minv\le v$且$s\le C+Aminh+Bminv$从小到大 ...
- Stupid && 祖传Fortran代码救赎之路(编译Dll)
Stupid && 祖传Fortran代码救赎之路(编译Dll) gfortran编译动态库 在Windows平台下,Intel Fortran安装过于庞大且费事(现在集成到OneAP ...
- 洛谷 P4183 - [USACO18JAN]Cow at Large P(点分治)
洛谷题面传送门 点分治 hot tea. 首先考虑什么样的点能够对以 \(u\) 为根的答案产生 \(1\) 的贡献.我们考虑以 \(u\) 为根对整棵树进行一遍 DFS.那么对于一个点 \(v\), ...
- 洛谷 P5401 - [CTS2019]珍珠(NTT+二项式反演)
题面传送门 一道多项式的 hot tea 首先考虑将题目的限制翻译成人话,我们记 \(c_i\) 为 \(i\) 的出现次数,那么题目的限制等价于 \(\sum\limits_{i=1}^D\lflo ...