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 自定义事件监听的更多相关文章

  1. Spring之事件监听(观察者模型)

    目录 Spring事件监听 一.事件监听案例 1.事件类 2.事件监听类 3.事件发布者 4.配置文件中注册 5.测试 二.Spring中事件监听分析 1. Spring中事件监听的结构 2. 核心角 ...

  2. Spring的事件监听机制

    最近公司在重构广告系统,其中核心的打包功能由广告系统调用,即对apk打包的调用和打包完成之后的回调,需要提供相应的接口给广告系统.因此,为了将apk打包的核心流程和对接广告系统的业务解耦,利用了spr ...

  3. [问题贴]mui.openWindow+自定义事件监听操作让alert()执行两次

    仔细看,Alert函数执行了两次 共两个页面:index.html和detail.html, detail.html为按钮设置了自定义事件监听(newsId),触发alert. 在index.html ...

  4. 十一、Spring之事件监听

    Spring之事件监听 ApplicationListener ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成Applica ...

  5. Spring的事件监听ApplicationListener

    ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件机制. 如果容器中存在Applica ...

  6. Java中的事件监听机制

    鼠标事件监听机制的三个方面: 1.事件源对象: 事件源对象就是能够产生动作的对象.在Java语言中所有的容器组件和元素组件都是事件监听中的事件源对象.Java中根据事件的动作来区分不同的事件源对象,动 ...

  7. java Gui编程 事件监听机制

    1.     GUI编程引言 以前的学习当中,我们都使用的是命令交互方式: 例如:在DOS命令行中通过javac java命令启动程序. 软件的交互的方式:   1. 命令交互方式    图书管理系统 ...

  8. Java界面编程—事件监听机制

    组件首先要先注册事件处理器,当用户单击组件.移动鼠标或者敲击键盘时都会产生事件(Event),一旦有时间发生,应用程序就会做出对该事件的响应,这些组件就是事件源(Event source). 接受.解 ...

  9. Java 中的事件监听机制

    看项目代码时遇到了好多事件监听机制相关的代码.现学习一下: java事件机制包含三个部分:事件.事件监听器.事件源. 1.事件:继承自java.util.EventObject类,开发人员自己定义. ...

随机推荐

  1. 4. 理解Update、Enter、Exit 与 添加、删除元素

    理解Update.Enter.Exit 与 添加.删除元素 在使用data()绑定数据时,例如:现在我们有一个数组[3,6,9,12,15],我们可以将数组每一项与一个<p>绑定,但是,现 ...

  2. LeetCode-40. 组合总和 II C++(回溯法)

    回溯法本身是种暴力解法,虽然效率之类的比较低,但是写起来比较易懂和快.在提交之后的排名也挺低的,大概就超过8%左右.以后复习的时候再去看看题解,看看更高性能的算法.这里先暂时贴上回溯法的代码. 最后说 ...

  3. Java学习(十三)

    今天学习了Java中的继承,Java的继承和c++的差别很大. 继承的基本作用是代码复用,但最重要的作用是为了以后的"方法覆盖"和"多态机制". 继承的语法是: ...

  4. HCNP Routing&Switching之BGP团体属性和团体属性过滤器

    前文我们了解了BGP的路由过滤已经as-path过滤器的使用相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15542559.html:今天我们来聊一聊 ...

  5. Mac 下安装 MySQL 步骤

    安装 MySQL Mac 下安装MySQL推荐去官网下载dmg 版本的,我使用的版本是5.7.30. 如上图所示. 之后就是傻瓜式一键狂点不过需要注意的是,不要关闭下图所示的框框!不要关闭下图所示的框 ...

  6. CAP 5.2 版本发布通告

    前言 今天,我们很高兴宣布 CAP 发布 5.2 版本正式版,在这个版本中,我们主要致力于更好的优化使用体验以及支持新的 Transport,同时在该版本也进行了一些 bug 修复的工作. 自从 5. ...

  7. 从零搭建vsftpd

    先吐槽一下这个工具,配置繁琐,限制规则复杂,报错信息不够详细,学起来吃力. 准备工作 [root@vsftp-server ~]# mkdir /data/ #创建ftp目录 [root@vsftp- ...

  8. Scrum精髓读书笔记

    Scrum精髓 四 . Sprint Sprint的定义 Scrum在最长一个月的迭代或周期中安排工作,一般为2个星期,这些迭代或周期称为Sprint Sprint提供基本的Scrum骨架,大多数其他 ...

  9. 在Winform框架的多文档界面中实现双击子窗口单独弹出或拖出及拽回的处理

    在基于DevExpress的多文档窗口界面中,我们一般使用XtraTabbedMdiManager来管理多文档窗口的一些特性,如顶部菜单,页面的关闭按钮处理,以及一些特殊的设置,本篇随笔介绍这些特点, ...

  10. Spring-boot -Web开发

    1).创建SpringBoot应用,选中我们需要的模块: 2).SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来 3).自己编写业务代码: 文件名的功能 x ...