JAVAWEB三剑客之Listenner

Listenner是什么

listenner顾名思义监听器,javaweb中的listenner旨在监听servlet容器中各个对象状态变化

这其中的各个对象主要包含三个对象

  • servletContext servlet应用上下文对象
  • 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<Observer> 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 <tt>Observable</tt> object's
     * <code>notifyObservers</code> method to have all the object's
     * observers notified of the change.
     *
     * @param   o     the observable object.
     * @param   arg   an argument passed to the <code>notifyObservers</code>
     *                 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收到了通知
发布了4 篇原创文章 · 获赞 1 · 访问量 118

猜你喜欢

转载自blog.csdn.net/weixin_43593829/article/details/105647793
今日推荐