Listenner是什么
listenner顾名思义监听器,javaweb中的listenner旨在监听servlet容器中各个对象的状态变化
这其中的各个对象主要包含三个对象
servletContextservlet应用上下文对象
session 用户session对象
servletRequest http请求对象
状态变化主要包含两种情况
对象的创建与销毁
对象属性的增加删除和替换
其中各个对象的各个状态变化的接口如下
ServletContext
Session
ServletRequest
对象的创建和销毁
ServletContextListener
HttpSessionListener
ServletRequestListener
对象那个属性的增加删除和替换
ServletContextAttributeListener
HttpSessionAttributeListener
ServletRequestAttributeListener
如何实现一个Listenner
我们以ServletContext为例子,实现ServletContext对象的创建和销毁,实现ServletContext属性的添加删除和更新,其他的对象跟这个类似
实现ServletContextListener
实现ServletContextListener接口,
实现 创建对象方法(contextInitialized),对象销毁方法(contextDestroyed)
加入注解@WebListener
@WebListener
public class MyServletContextListenner implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce){
System.out.println("contextInitialized");
}
@Override
public void contextDestroyed(ServletContextEvent sce){
System.out.println("contextDestroyed");
}
}
复制代码
实现ServletContextAttributeListener
实现ServletContextAttributeListener接口
实现 新增删除更新方法
加入注解@WebListener
@WebListener
public class MyServletContextAttributeLisener implements ServletContextAttributeListener{
@Override
public void attributeAdded(ServletContextAttributeEvent scae){
System.out.println("servletContext attributeAdded");
}
@Override
public void attributeRemoved(ServletContextAttributeEvent scae){
System.out.println("servletContext attributeRemoved");
}
@Override
public void attributeReplaced(ServletContextAttributeEvent scae){
System.out.println("servletContext attributeReplaced");
}
}
复制代码
启动应用
启动应用,发送一个请求,关闭应用,可以看到已经对对应的事件进行了回调
Listenner有什么用
listenner的作用主要在于对各种事件的回调,当某件事件触发后,我们可以对其进行自定义的业务逻辑处理,比如Springmvc框架中,会有ContextLoaderListener这么一个实现,它会监听contextInitialized的调用,并在调用中初始化spring的上下文WebApplicationContext,初始化完成之后会将这个上下文对象存放到ServletContext的属性中,以便于在后续通过ServletContext来获取这个对象,同时也会监听contextDestroyed这个方法,以便于在servlet被销毁时,可以关闭spring容器,关闭各种连接,执行销毁逻辑等等,后续会专门写一篇关于Springmvc初始化和销毁的文章,这里就点到为止
观察者模式
Listenner是观察者模式的典型实现,当对象之间存在一对多关系,并且存在行为影响关系时,则可以使用观察者模式
观察者模式中主要设计到两个概念,目标主题和观察者,,观察者订阅主题的消息,当主题行为改变发布消息时,会自动触发观察者的回调,下面我们基于JDK自带的Observer 来实现观察者模式
JDK自带的主题抽象
jdk自带的Observable对象,主要属性changed表示当前是否发生改变,obs表示当前观察者列表,notifyObservers方法用来通知观察者当前已经发生变化
public class Observable{
private boolean changed = false;
private Vector obs;
public Observable(){
obs = new Vector<>();
}
public synchronized void addObserver(Observer o);
public void notifyObservers();
}
复制代码
Observer则是观察者的抽象,只有一个update方法,用来做通知回调,也就是说当Observable调用notifyObservers方法后,将调用Observer的update方法
public interface Observer{
/**
* This method is called whenever the observed object is changed. An
* application calls an Observable object's
* notifyObservers
method to have all the object's
* observers notified of the change.
*
* @param o the observable object.
* @param arg an argument passed to the notifyObservers
* method.
*/
void update(Observable o, Object arg);
}
复制代码
上面两个类只是JDK提供给我的抽象,具体的实现还需要我们根据自己的场景来设计
实现一个主题对象,主要继承Observable,在notice方法中,主要是调用了Observable的setChanged,修改changed属性为true,表示当前有改动,紧接着调用notifyObservers用来通知所有观察者
public class Publish extends Observable{
public void notice(){
System.out.println("publish 发送了通知");
setChanged(); //设置changed状态为true
notifyObservers(); //调用父类Observable方法,通知所有观察者
}
}
复制代码
实现一个观察者SubScribe,实现Observer接口,实现update方法,主要看是否有对应回调
public class SubScribe implements Observer{
private Integer no;
public SubScribe(Integer no){
this.no=no;
}
@Override
public void update(Observable o, Object arg){
System.out.println("观察者"+no+"收到了通知");
}
}
复制代码
新建一个主题对象,并且添加两个观察者,最后主题对象发布通知
public static void main(String[] args){
Publish publish = new Publish();
SubScribe subscribe1 = new SubScribe(1);
SubScribe subscribe2 = new SubScribe(2);
publish.addObserver(subscribe1);
publish.addObserver(subscribe2);
publish.notice();
}
复制代码
结果
publish 发送了通知
观察者2收到了通知
观察者1收到了通知
复制代码