监视器

监视器

监听器的概述:

概念:

用于监听Web程序在执行过程中作用域(上下文域、会话域、请求域)中发生的一些事件,如:监听作用域的创建和销毁,增加属性,修改属性,删除属性值等。监听器对象可以在事情发生前、发生后做一些必要的处理。

监听的两种类型:
  1. 对域对象的创建与销毁的行为进行监听

  2. 对域中的属性增删改的行为进行监听

    • 所有的监听器都是由事件触发时执行,不由用户主动调用。

    • 使用场景:

    • 统计在线人数

    • 显示登录的用户的详细信息

    • Web项目启动和关闭时处理的工作

监听机制的组成

image

监听机制的对象描述
事件源发出事件的对象,域对象:上下文域ServletContext,会话域,请求域
事件事件本身,ServletContextEvent类,做为参数传递给监听者
监听者对事件进行处理的类,这个类需要实现监听器的接口,XxxListener接口
监听器的分类

事件源监听器接口时机
ServletContextServletContextListener上下文域创建和销毁接口
ServletContextServletContext**Attribute**Listener上下文域中属性变化的监听接口
HttpSessionHttpSessionListener会话域创建和销毁接口
HttpSessionHttpSession**Attribute**Listener会话域中属性变化的监听接口
ServletRequestServletRequestListener请求域创建和销毁接口
ServletRequestServletRequest**Attribute**Listener请求域中属性变化的监听接口

ServletContextListener监听器
  • 作用: 用于监听上下文对象的创建和销毁
  • 运行时机:

    • 创建:服务器启动加载当前项目的时候
    • 销毁:服务器关闭的时候
  • 方法:

    • 接口中的方法
    功能
    void contextDestroyed(ServletContextEvent sce)用于监听上下文对象销毁时方法,传递了事件对象
    void contextInitialized(ServletContextEvent sce)用于监听上下文对象创建时方法
  • ServletContextEvent中的方法

    • ServletContext getServletContext() 得到上下文对象
ServletContextAttributeListener监听器
  • 作用:监听上下文域中属性变化
  • 时机:

    • 增:application.setAttribute()
    • 删:application.removeAttribute()
    • 改:application.setAttribute(同名)
    • 上面每一个动作都会触发下面的方法的
  • 接口方法中的方法:

    接口中的方法功能
    void attributeAdded(ServletContextAttributeEvent event)添加属性的时候监听方法
    void attributeRemoved(ServletContextAttributeEvent event)删除属性的时候监听方法
    void attributeReplaced(ServletContextAttributeEvent event)修改属性的时候监听方法
  • ServletContextAttributeEvent对象中的方法

    ServletContextAttributeEvent对象中的方法功能
    String getName()得到属性的名字
    Object getValue()得到属性的值
    ServletContext getServletContext()得到上下文对象
  • 示范

<%
//添加属性
application.setAttribute("user", "猪八戒");

//修改属性
application.setAttribute("user", "嫦娥");

//删除属性
application.removeAttribute("user");
%>

image

@Override
public void contextInitialized(ServletContextEvent sce) {
    System.out.println("上下文域被创建了, 得到上下文域对象:" + sce.getServletContext());

}

//上下文域销毁
@Override
public void contextDestroyed(ServletContextEvent sce) {
    System.out.println("上下文域被销毁");
}

//属性添加
@Override
public void attributeAdded(ServletContextAttributeEvent scab) {
    System.out.println("添加了属性名:" + scab.getName() + ",属性值:" + scab.getValue());
}

//属性删除
@Override
public void attributeRemoved(ServletContextAttributeEvent scab) {
    System.out.println("删除了属性名:" + scab.getName() + ",属性值:" + scab.getValue());
}

//属性修改
@Override
public void attributeReplaced(ServletContextAttributeEvent scab) {
    System.out.println("修改前属性名:" + scab.getName() + ",属性值:" + scab.getValue());
    System.out.println("修改后属性名:" + scab.getName() + ",属性值:" + scab.getServletContext().getAttribute( scab.getName()));
}

HttpSessionListener的概述:

  • 作用: 会话创建和销毁监听器
  • 时机:

    • 创建:用户第1次访问服务器,并且调用request.getSession()

    • 销毁:会话过期

      • setMaxInactiveInterval(秒)
      • web.xml配置分
      • invalidate() 立即失效
  • 接口中的方法
    • void sessionCreated(**HttpSessionEven**t se) 会话创建监听方法
    • void sessionDestroyed(HttpSessionEvent se) 会话销毁监听方法
HttpSessionAttributeListener监听器
  • 作用: 对会话域中的属性增删改监听
  • 时机:
    • 增:session.setAttribute()
    • 删:session.removeAttribute()
    • 修:session.setAttribute(同名)
    • 上面的每一个动作都会触发下面的方法
  • 接口中的方法

    接口中的方法功能
    void attributeAdded(HttpSessionBindingEvent event)会话域中添加属性的时候监听方法
    void attributeRemoved(HttpSessionBindingEvent event)会话域中删除属性的时候监听方法
    void attributeReplaced(HttpSessionBindingEvent event)会话域中修改属性的时候监听方法

ServletRequestListener的作用

  • 作用:
    请求的创建和销毁监听器
  • 时机:

    • 创建:发送请求的时候
    • 销毁:响应结束的时候
  • 接口中的方法

    接口中的方法功能
    void requestDestroyed(ServletRequestEvent sre)请求对象销毁的时候处理方法
    void requestInitialized(ServletRequestEvent sre)请求对象创建的时候处理方法
ServletRequestAttributeListener的使用

请求域中的属性创建和销毁监听器

接口中的方法功能
void attributeAdded(ServletRequestAttributeEvent srae)请求域中添加属性的监听方法
void attributeRemoved(ServletRequestAttributeEvent srae)请求域中删除属性的监听方法
void attributeReplaced(ServletRequestAttributeEvent srae)请求域中修改属性的监听方法

案例 统计网站在线访客人数

image

实现思路:
- 服务器创建会话的个数,与用户访客的个数是相同的。
- 设计一个成员变量用于存储网站访客的人数: int onLineCount = 0;
- 在sessionCreated方法中onLineCount加1
- 把onLineCount的值放入上下文域中,供所有用户共享。
- 在sessionDestoryed中,用户数量减1,onLineCount–,并更新context域中的值。
- 在页面上,从context域中取出用户数量,输出。
- 创建JSP页面显示用户数,创建logout.jsp退出。
- 如果要用线程安全的计数器,可以使用AtomicInteger类

image

/*
统计在线人数
 */
public class CounterUserListener implements HttpSessionListener {

    //设计一个成员变量用于存储网站访客的人数,避免线程安全问题
    private AtomicInteger onLineCount = new AtomicInteger();

    //只要创建一个新的会话,人数加1
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("创建会话:" + se.getSession().getId());
        //在sessionCreated方法中onLineCount加1
        // onLineCount++;
        onLineCount.incrementAndGet();   //相当于加1
        //把onLineCount的值放入上下文域中,供所有用户共享。
        se.getSession().getServletContext().setAttribute("count", onLineCount);
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("销毁会话:" + se.getSession().getId());
        //在sessionDestoryed中,用户数量减1,
        // onLineCount--;
        onLineCount.decrementAndGet();    //相当于减1
        //并更新context域中的值        
        se.getSession().getServletContext().setAttribute("count", onLineCount);
    }

}

JSP

<body>
    <h2>您好,你是第${applicationScope.count}个在线的访客</h2>
    <a href="logout.jsp">退出</a>
</body>

AtomicInteger类

java中关于AtomicInteger的使用

JAVA 中无锁的线程安全整数 AtomicInteger介绍和使用

在Java语言中,++i和i++操作并不是线程安全的,在使用的时候,不可避免的会用到synchronized关键字。而AtomicInteger则通过一种线程安全的加减操作接口。

是一个原子操作

AtomicInteger Atomic =new AtomicInteger();
Atomic.incrementAndGet();//相当于加1
Atomic.decrementAndGet();//相当于减1

Java.util.concurrent中实现的原子操作类包括:
AtomicBoolean、AtomicInteger、AtomicIntegerArray、AtomicLong、AtomicReference、AtomicReferenceArray。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值