容器内部事件发布

Spring的applicationContext容器提供的容器内事件发布功能,是通过java提供的自定义事件实现的

事件类型:eventObject 类继承

事件监听:eventListener 接口实现

定义事件类型

package event;

import java.util.EventObject;

/**
*
* Title: MethodExecutionEvent.java
* Description: 定义一个自定义的事件对象
* @author xiaof
* @date 2018年3月28日
* @version 1.0
*
*/
public class MethodExecutionEvent extends EventObject {
/**
*
*/
private static final long serialVersionUID = -2324856893034735293L; private String methodName; /**
* 构造函数是,继承的类实现的
* @param source
*/
public MethodExecutionEvent(Object source) {
super(source);
} public MethodExecutionEvent(Object source, String methodName) {
super(source);
this.methodName = methodName;
} public String getMethodName() {
return methodName;
} public void setMethodName(String methodName) {
this.methodName = methodName;
} }

创建自定义事件类的监听接口

package event;

import java.util.EventListener;

public interface MethodExecutionEventListener extends EventListener {

    /**
* 处理方法开始执行的时候发布的methodexecutionevent事件
* @param evt
*/
void onMethodBegin(MethodExecutionEvent evt); /**
* 处理方法开结束执行的时候发布的methodexecutionevent事件
* @param evt
*/
void onMethodEnd(MethodExecutionEvent evt); }

发布事件

package event;

import java.util.ArrayList;
import java.util.List; /**
*
* Title: MethodExeuctionEventPublisher.java
* Description: 事件发布
* @author xiaof
* @date 2018年3月28日
* @version 1.0
*
*/
public class MethodExeuctionEventPublisher { private List<MethodExecutionEventListener> listeners = new ArrayList<MethodExecutionEventListener>(); public void methodToMonitor() {
MethodExecutionEvent event2Publish = new MethodExecutionEvent(this, "methodToMonitor");
this.publishEvent(MethodExecutionStatus.BEGIN, event2Publish);
//实际其他方法逻辑 this.publishEvent(MethodExecutionStatus.END, event2Publish); } protected void publishEvent(MethodExecutionStatus status, MethodExecutionEvent methodExecutionEvent) { List<MethodExecutionEventListener> copyListeners = new ArrayList<MethodExecutionEventListener>(listeners); //循环发布
for(MethodExecutionEventListener listener : copyListeners) { if(MethodExecutionStatus.BEGIN.equals(status)) {
listener.onMethodBegin(methodExecutionEvent);
} else {
listener.onMethodEnd(methodExecutionEvent);
}
}
} public void addMethodExecutionListener(MethodExecutionEventListener listener) {
this.listeners.add(listener);
} public void removeListener(MethodExecutionEventListener listener) {
if(this.listeners.contains(listener)) {
this.listeners.remove(listener);
}
} public void removeAllListeners() {
this.listeners.clear();
} public static void main(String[] args) { MethodExeuctionEventPublisher eventPublisher = new MethodExeuctionEventPublisher(); eventPublisher.addMethodExecutionListener(new SimpleMethodExecutionEventListener()); eventPublisher.methodToMonitor(); }
}
那么spring的容器内事件的发布类结构是什么样的呢?

Spring的事件类型分一下三种

我们主要使用一下几个

在spring容器中,这四个重上到下,分别是:

容器关闭的时候发布的事件类型

容器在初始化的时候或者刷新的时候发布

当使用 ConfigurableApplicationContext 接口中的 start() 方法启动 ApplicationContext 时,该事件被发布

当使用 ConfigurableApplicationContext 接口中的 stop() 方法停止 ApplicationContext 时,发布这个事件。你可以在接受到这个事件后做必要的清理的工作。

RequestHandledEvent   web请求处理后发布的事件

spring监听事件

application在启动的时候,会自动识别并加载eventlistner类型bean定义。

一旦容器内有事件发布,将通知这些注册到容器的eventlistener

ApplicationListener

Spring发布事件

ApplicationEventPublisher  接口 实现对象 ApplicationContext  也是一个事件发布对象

这里做一个小测试:

package cn.cutter.start.event;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.stereotype.Component; @Component
public class MyStartEventHandler implements ApplicationListener<ContextStartedEvent> { @Override
public void onApplicationEvent(ContextStartedEvent event) {
System.out.println("cutter_point 启动application容器");
} }
package cn.cutter.start.event;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.stereotype.Component; @Component
public class MyStopEventHandler implements ApplicationListener<ContextStoppedEvent> { @Override
public void onApplicationEvent(ContextStoppedEvent event) {
System.out.println("cutter_point 停止application容器");
} }
package cn.cutter.start.event;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;
import org.springframework.stereotype.Component; @Component
public class MyStopEventHandler2 implements ApplicationListener<ContextStoppedEvent> { @Override
public void onApplicationEvent(ContextStoppedEvent event) {
// TODO Auto-generated method stub
System.out.println("cutter_point 停止application容器 222");
} }
package cn.cutter.start.resourceloader;

import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.ResourceLoader; public class FooBar implements ResourceLoaderAware { //资源加载器
private ResourceLoader resourceLoader; public void foo(String location) {
//这里有没有很熟悉
// ResourceDemo.class.getResource(location).getClass()
System.out.println(this.getResourceLoader().getResource(location).getClass());
} @Override
public void setResourceLoader(ResourceLoader resourceLoader) {
//这里进行resourceloader的注入
this.resourceLoader = resourceLoader;
} public ResourceLoader getResourceLoader() {
return resourceLoader;
} public void sayFoo() {
System.out.println("hi foo!");
} }
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <context:component-scan base-package="cn.cutter" /> <!-- 国际化配置 -->
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basenames">
<list>
<value>i18/users</value>
<value>i18/errormsg</value>
</list>
</property> </bean> <bean id="ttmRateService" class="cn.cutter.simplefx.service.impl.MockTTMRateServiceImpl"></bean> <bean id="fooBar" class="cn.cutter.start.resourceloader.FooBar" /> <bean id="fooBar2" class="cn.cutter.start.resourceloader.FooBar2" /> <bean id="resourceDemo" class="cn.cutter.start.resourceloader.ResourceDemo">
<property name="resource">
<value>classpath:applicationContext-bean.xml</value>
</property>
</bean> <!-- <bean id="myObject" class="cn.cutter.start.bean.MyObject"></bean> --> <!-- <alias name="FXNewsProvider" alias="provideralias"/> --> <!-- <bean id="test4key2" ></bean> <bean id="" class="..." lazy-init="true">
<constructor-arg>
<ref bean="" parent=""/>
</constructor-arg> <property name="test1">
<value>ttttt1</value>
<idref bean="ttttt1"/>
</property> <property name="test2">
<list>
<value>test2value</value>
<ref bean="test2222"/>
<idref bean="test22222"/>
<bean class="..."></bean>
</list>
</property> <property name="test3">
<set>
<value>test2value</value>
<ref bean="test2222"/>
<idref bean="test22222"/>
<bean class="..."></bean>
</set>
</property> <property name="test4">
<map>
<entry key="test4key1">
<value>something</value>
</entry> <entry key-ref="test5key2">
<list>
<value>test2value</value>
<ref bean="test2222"/>
<idref bean="test22222"/>
<bean class="..."></bean>
</list>
</entry>
</map>
</property> </bean> --> </beans>
启动测试案例
@Test
public void testEvent() {
//这里出发start事件和stop事件,就是使用ConfigurableApplicationContext的start和stop事件
ConfigurableApplicationContext cac = (ConfigurableApplicationContext) before(); cac.start();
FooBar fooBar = (FooBar) cac.getBean("fooBar");
fooBar.sayFoo();
cac.stop(); }
运行截图

最新文章

  1. [EF2]Sneak Preview: Persistence Ignorance and POCO in Entity Framework 4.0
  2. (三)策略模式-C++实现
  3. Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收
  4. js 字符串类型转为数组类型
  5. ecmall二次开发 直接实例化mysql对象
  6. POJ 3687 Labeling Balls【拓扑排序 优先队列】
  7. Android 使用库项目时的一个特殊tip
  8. Shell遍历文件,对每行进行正则匹配
  9. 关于Fragment与Activity的想法
  10. (转帖)oracle sql 语句优化
  11. CSS 弹性盒子布局
  12. Android - FEATURE_NO_TITLE
  13. 嵌入式linux开发之工具------tftp
  14. BZOJ 1040: [ZJOI2008]骑士 [DP 环套树]
  15. 冲刺NO.1
  16. VB6进行GZIP解压&amp;C#进行GZIP压缩和解压
  17. linux系统如何发送邮件
  18. Tornado学习笔记(一) helloword/多进程/启动参数
  19. 分析java内存情况
  20. python全栈开发 * 22 面向对象 知识点汇总 * 180703

热门文章

  1. openstack之安全组管理
  2. 利用cglib包实现Spring中aop的&lt;aop:advisor&gt;功能
  3. 【慕课网实战】Spark Streaming实时流处理项目实战笔记五之铭文升级版
  4. (转)ASP.NET MVC3 Razor视图引擎-基础语法
  5. checked 选择框选中
  6. flask + apidoc 生成接口文档(附加一个坑)
  7. 待了解概念_GraphicsView
  8. 最基本的CentOS 网络配置
  9. [ 9.13 ]CF每日一题系列—— 340A GCD &amp; LCM
  10. poj2478 Farey Sequence 欧拉函数的应用