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方法
原文地址:https://www.cnblogs.com/perfei/p/12183405.html
时间: 2024-11-07 13:20:32