ApplicationContext 事件
定义一个context的起动监听事件
importorg.springframework.context.ApplicationListener;importorg.springframework.context.event.ContextStartedEvent;public class EventStart implements ApplicationListener{
@Overridepublic voidonApplicationEvent(ContextStartedEvent arg0) {
System.out.println("上下文 开始 事件");
}
}
要定义一个事件监听,首先你得有一个事件,ContextStartedEvent 是一个固定的、具体的事件,Java spring自带的,通过实现
ApplicationListener
就可以监控这个事件了
ContextStartedEvent 的定义
@SuppressWarnings("serial")public class ContextStartedEvent extendsApplicationContextEvent {/*** Create a new ContextStartedEvent.
*@paramsource the {@codeApplicationContext} that has been started
* (must not be {@codenull})*/
publicContextStartedEvent(ApplicationContext source) {super(source);
}
}
importorg.springframework.context.ApplicationListener;importorg.springframework.context.event.ContextStoppedEvent;public class EventStop implements ApplicationListener{
@Overridepublic voidonApplicationEvent(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.洪七公
初始化 bean.null家
我
上下文 开始 事件
部门领导洪七公
上下文 停止 事件
销毁 bean.null销毁 bean.洪七公
为什么主方法中一调用 start 方法,监听事件就可以自己被调用 呢
start方法真正执行的是AbstractApplicationContext的start方法,在方法里,除了真正start要处理的内容外,还额外加了事件处理,
@Overridepublic voidstart() {
getLifecycleProcessor().start();
publishEvent(new ContextStartedEvent(this));
}
所加的事件就是ContextStartedEvent事件,在将实例了ApplicationListener的bean通过xml注册到spring容器中时,容器自动调用了该bean的onApplicationEvent方法
自定义事件
public classPerson {privateString name;publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}
}
public class Work extendsApplicationEvent{private static final long serialVersionUID = 1L;privatePerson ps;public voidsetPs(Person ps) {this.ps =ps;
}publicWork(Object source) {super(source);
}public voiddoWorking() {
String name= this.ps.getName();
System.out.println(name+ " 今天没有完成100张图片制作,并且听到这个任务时,情绪时而激动,时而低落");
}
}
//该类要注册到spring容器,然后容器会自动调用实现ApplicationListener接口的类的onApplicationEvent方法
public class WorkListener implements ApplicationListener{
@Overridepublic voidonApplicationEvent(Work event) {//TODO Auto-generated method stub
System.out.println("摄像头记录到:");
event.doWorking();
}
}
public class Sleep extendsApplicationEvent{privatePerson ps;public voidsetPs(Person ps) {this.ps =ps;
}private static final long serialVersionUID = 2L;publicSleep(Object source) {super(source);
}public voiddoSleeping() {
String name= this.ps.getName();
System.out.println(name+ " 开始休息了");
}
}
//该类要注册到spring容器,然后容器会自动调用实现ApplicationListener接口的类的onApplicationEvent方法
public class SleepListener implements ApplicationListener{
@Overridepublic voidonApplicationEvent(Sleep event) {
System.out.println("摄像头记录到:");
event.doSleeping();
}
}
public class Report implementsApplicationEventPublisherAware{privateApplicationEventPublisher publisher;
@Overridepublic voidsetApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.publisher =applicationEventPublisher;
}public voidwork() {
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 voidsleep() {
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);
}
}
public classMain {public static voidmain(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方法