1.引言
spring框架有四个基础核心:
- IoC容器
- JavaConfig
- 事件监听
- Spring factories
2.事件监听
关于什么是事件监听?
有一定开发经验的朋友,事件监听都不陌生。在我刚毕业的的时候,以至还在学校的时候,还一定程度上有机会见识java桌面应用开发(swing),当然今天其实也还有基于swing开发的一些工具型应用,比如大名鼎鼎的性能压测工具:Jmeter。
为什么我会提到swing桌面应用开发呢?因为做过GUI开发的同学,对事件监听这个事显得更亲切!
话说回来,你要没有做过桌面应用开发,也没有关系。基于servlet的web应用开发,里面是不是也有监听器?比如说:ServletRequestListener,SessionListener,ServletContextListener等
哪怕没有机会写原生的servlet,spring 框架提供的ContextLoaderListener,总还有印象的吧!
话说回来,事件监听到底是怎么一回事呢?它其实就是观察者模式的体现,比如考试的时候,有监考老师时刻盯着你,一旦你作弊,或者想作弊,监考老师马上直勾勾的看着你。像这样的
spring 提供事的件监听
在基于spring的应用中,有时候我们需要在应用启动的时候,做一些初始化资源的事情,比如说线程池、比如说初始化调度任务。可以通过扩展ApplicationListener来承担实现这样的需求,ApplicationListener即是spring框架提供的监听器。
spring应用提供了完整的事件监听组件
- 事件:ApplicationEvent,在spring应用启动的时候,会通过ApplicationContext发布相关的事件,比如刷新容器事件ContextRefreshedEvent,比如容器关闭事件ContextClosedEvent
- 事件监听器:ApplicationListener,监听处理通过ApplicationContext发布的相关事件
- 事件发布者:ApplicationContext
基于以上组件,可以灵活进行扩展实现各种需求。只需要扩展ApplicationListener接口,监听特定类型事件,再通过ApplicationContext在合适的时机发布事件即可。
java原生事件监听案例
spring提供了完整的事件监听机制,如果我们不使用spring框架,或者说我想知道spring框架的事件监听的底层实现。事实上非常简单!java原生就提供了事件监听的机制和组件
- 事件:EventObject
- 监听器:EventListener
基于以上两个组件,我们就能实现满足应用需要的事件监听。下面跟着我来完成一个案例,看完案例相信你就能明白了。
案例说明:通过原生的java事件监听组件,实现统计方法执行耗时。
扩展事件
package com.anan.edu.common.event;
import java.util.EventObject;
/**
* 方法执行耗时 事件 Event
*
* @author ThinkPad
*/
public class MonitorMethodTimeEvent extends EventObject {
/**
* 时间
*/
public Long time;
public MonitorMethodTimeEvent(Object source) {
super(source);
}
}
扩展监听器
接口:
package com.anan.edu.common.event;
import java.util.EventListener;
/**
* 事件监听器接口
*
* @author ThinkPad
*/
public interface MonitorMethodTimeEventListener extends EventListener{
/**
* 方法开始
* @param event
*/
void onBegin(MonitorMethodTimeEvent event);
/**
* 方法结束
* @param event
*/
void onEnd(MonitorMethodTimeEvent event);
}
实现类:
package com.anan.edu.common.event;
import lombok.extern.slf4j.Slf4j;
/**
* 事件监听器具体实现
*
* @author ThinkPad
*/
@Slf4j
public class MyMonitorMethodTimeEventListener implements MonitorMethodTimeEventListener {
/**
* 方法开始
*
* @param event
*/
@Override
public void onBegin(MonitorMethodTimeEvent event) {
event.time = System.currentTimeMillis();
}
/**
* 方法结束
*
* @param event
*/
@Override
public void onEnd(MonitorMethodTimeEvent event) {
Long time = System.currentTimeMillis() - event.time;
log.info("方法执行耗时:{}", time);
}
}
定义事件发布者
package com.anan.edu.common.event;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
/**
* 事件发布者
*
* @author ThinkPad
*/
public class MonitorMethodTimeEventPublisher {
// 监听器集合
private static List<MonitorMethodTimeEventListener> list =
new ArrayList<MonitorMethodTimeEventListener>();
public static void main(String[] args) {
// 监听器
MonitorMethodTimeEventListener listener = new MyMonitorMethodTimeEventListener();
list.add(listener);
// 方法监听
MonitorMethodTimeEventPublisher publisher = new MonitorMethodTimeEventPublisher();
publisher.monitor();
}
/**
* 监听
*/
public void monitor(){
// 发布事件
MonitorMethodTimeEvent event = new MonitorMethodTimeEvent(this);
publishEvent("begin", event);
// 模拟方法执行时间
try {
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(10));
} catch (InterruptedException e) {
e.printStackTrace();
}
publishEvent("end", event);
}
/**
* 发布事件
* @param type
* @param event
*/
private static void publishEvent(String type,MonitorMethodTimeEvent event){
list.forEach(listener ->{
if("begin".equals(type)){
listener.onBegin(event);
}else if("end".equals(type)){
listener.onEnd(event);
}
});
}
}
通过以上代码,即完成了一个java原生事件监听的案例。我们说万变不离其宗,当你在使用各种开发框架,比如spring,比如mybatis框架的时候,它们所提供的事件监听不外乎是如此。