Java三大器之监听器(Listener)的工作原理和代码演示

现在来说说Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的服务器端程序,它也是随web应用的启动
而启动,只初始化一次,随web应用的停止而销毁。主要作用是:做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些

固定的对象等等。首先来看一下ServletContextListener接口的源代码:

 
  1. public abstract interface ServletContextListener extends EventListener{

  2. public abstract void contextInitialized(ServletContextEvent paramServletContextEvent);

  3. public abstract void contextDestroyed(ServletContextEvent paramServletContextEvent);

  4. }


下面利用监听器对数据库连接池DataSource的初始化演示它的使用:ListenerTest.java

 
  1. import javax.servlet.ServletContext;

  2. import javax.servlet.ServletContextEvent;

  3. import javax.servlet.ServletContextListener;

  4. import org.apache.commons.dbcp.BasicDataSource;

  5. /**

  6. * 现在来说说Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener 接口的

  7. * 服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。主要作用是:做一些初始化

  8. * 的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。

  9. *

  10. * 示例代码:使用监听器对数据库连接池DataSource进行初始化

  11. */

  12. public class ListenerTest implements ServletContextListener{

  13. // 应用监听器的销毁方法

  14. public void contextDestroyed(ServletContextEvent servletContextEvent) {

  15. ServletContext servletContext = servletContextEvent.getServletContext();

  16. // 在整个web应用销毁之前调用,将所有应用空间所设置的内容清空

  17. servletContext.removeAttribute("dataSource");

  18. System.out.println("销毁工作完成...");

  19. }

  20. // 应用监听器的初始化方法

  21. public void contextInitialized(ServletContextEvent servletContextEvent) {

  22. // 通过这个事件可以获取整个应用的空间

  23. // 在整个web应用下面启动的时候做一些初始化的内容添加工作

  24. ServletContext servletContext = servletContextEvent.getServletContext();

  25. // 设置一些基本的内容;比如一些参数或者是一些固定的对象

  26. // 创建DataSource对象,连接池技术 dbcp

  27. BasicDataSource basicDataSource = new BasicDataSource();

  28. basicDataSource.setDriverClassName("com.jdbc.Driver");

  29. basicDataSource.setUrl("jdbc:mysqlocalhost:3306/");

  30. basicDataSource.setUsername("root");

  31. basicDataSource.setPassword("root");

  32. basicDataSource.setMaxActive(10);//最大连接数

  33. basicDataSource.setMaxIdle(5);//最大管理数

  34. //bds.setMaxWait(maxWait); 最大等待时间

  35. // 把 DataSource 放入ServletContext空间中,

  36. // 供整个web应用的使用(获取数据库连接)

  37. servletContext.setAttribute("dataSource", basicDataSource);

  38. System.out.println("应用监听器初始化工作完成...");

  39. System.out.println("已经创建DataSource...");

  40. }

  41. }


web.xml中配置如下,很简单:

 
  1. <!-- 配置应用监听器 -->

  2. <listener>

  3. <listener-class>com.ycq.ListenerTest</listener-class>

  4. </listener>


这样配置好了之后,以后在web应用中就可以通过ServletContext取得BasicDataSource对象,从而获取与数据库的连接,提高性能,方便使用。

示例代码二:

 
  1. import java.io.File;

  2. import javax.servlet.ServletContextEvent;

  3. import javax.servlet.ServletContextListener;

  4. import com.i2f.fsp.deploy.TransactionDeployer;

  5. /**

  6. * 监听器随着项目的启动而启动

  7. *

  8. */

  9. public class ListenerTest2 implements ServletContextListener{

  10. // 销毁监听器

  11. public void contextDestroyed(ServletContextEvent servletContextEvent) {

  12. System.out.println("date20161020095500 :" + servletContextEvent.getServletContext());

  13. }

  14. public void contextInitialized(ServletContextEvent servletContextEvent) {

  15. try{

  16. // 获取项目跟路径

  17. String basePath = servletContextEvent.getServletContext().getRealPath("/");

  18. // D:\apache-tomcat-6.0.41\webapps\i2money\ 绝对路径

  19. System.out.println("basePath20161020094700 :" + basePath);

  20. if (!(basePath.endsWith(File.separator))){

  21. basePath = basePath + File.separator;

  22. }

  23. basePath = basePath + "WEB-INF" + File.separator + "classes" + File.separator;

  24. new TransactionDeployer(basePath).deploy();

  25. // D:\apache-tomcat-6.0.41\webapps\i2money\WEB-INF\classes\

  26. System.out.println("basePath20161020094701 :" + basePath);

  27. }

  28. catch (Exception e){

  29. e.printStackTrace();

  30. System.exit(-1);

  31. }

  32. }

  33. }


示例代码三:

 
  1. import javax.servlet.http.HttpSession;

  2. import javax.servlet.http.HttpSessionEvent;

  3. import javax.servlet.http.HttpSessionListener;

  4. import org.apache.commons.logging.Log;

  5. import org.apache.commons.logging.LogFactory;

  6. import org.springframework.context.ApplicationContext;

  7. import org.springframework.web.context.support.WebApplicationContextUtils;

  8. public class UserLogoutListener implements HttpSessionListener{

  9. protected final Log log = LogFactory.getLog(super.getClass());

  10. public void sessionCreated(HttpSessionEvent event){

  11. this.log.error("session created. id = " + event.getSession().getId());

  12. }

  13. public void sessionDestroyed(HttpSessionEvent event){

  14. this.log.error("session destroyed.id = " + event.getSession().getId());

  15. HttpSession session = event.getSession();

  16. ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(session.getServletContext());

  17. OnlineUserMonitorClient client = (OnlineUserMonitorClient)context.getBean("onlineUserMonitorClient");

  18. client.afterSessionDestroyed(session);

  19. }

  20. }


监听器在实际项目中的应用,监听器在java web中应用的较多,比如:统计当前在线人数、自定义session扫描器。
--------------------- 应用一:统计当前在线人数 ---------------------

 
  1. import javax.servlet.ServletContext;

  2. import javax.servlet.http.HttpSessionEvent;

  3. import javax.servlet.http.HttpSessionListener;

  4. /**

  5. * @description HttpSessionListener监听器实现统计网站在线人数的功能

  6. */

  7. public class SessionListener implements HttpSessionListener{

  8. public static int TOTAL_ONLINE_USERS = 0;

  9. public void sessionCreated(HttpSessionEvent httpSessionEvent) {

  10. ServletContext servletContext = httpSessionEvent.getSession().getServletContext();

  11. TOTAL_ONLINE_USERS = (Integer) servletContext.getAttribute("TOTAL_ONLINE_USERS");

  12. // 如果用户退出,TOTAL_ONLINE_USERS自减1

  13. if(TOTAL_ONLINE_USERS == 0){

  14. servletContext.setAttribute("TOTAL_ONLINE_USERS", 1);

  15. }

  16. else{

  17. TOTAL_ONLINE_USERS--;

  18. servletContext.setAttribute("TOTAL_ONLINE_USERS", TOTAL_ONLINE_USERS);

  19. }

  20. }

  21. public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {

  22. ServletContext servletContext = httpSessionEvent.getSession().getServletContext();

  23. TOTAL_ONLINE_USERS = (Integer) servletContext.getAttribute("TOTAL_ONLINE_USERS");

  24. // 如果用户登录,TOTAL_ONLINE_USERS自增1

  25. if(TOTAL_ONLINE_USERS == 0){

  26. servletContext.setAttribute("TOTAL_ONLINE_USERS", 1);

  27. }

  28. else{

  29. TOTAL_ONLINE_USERS++;

  30. servletContext.setAttribute("TOTAL_ONLINE_USERS", TOTAL_ONLINE_USERS);

  31. }

  32. }

  33. }


--------------------- 应用二:自定义session扫描器 ---------------------

 
  1. import java.util.LinkedList;

  2. import java.util.List;

  3. import java.util.Timer;

  4. import javax.servlet.ServletContextEvent;

  5. import javax.servlet.ServletContextListener;

  6. import javax.servlet.http.HttpSession;

  7. import javax.servlet.http.HttpSessionEvent;

  8. import javax.servlet.http.HttpSessionListener;

  9. import jeus.util.concurrent50.Collections;

  10. /**

  11. * @description 当网站用户量增加时,session占用的内存会越来越大,这时session的管理,将会是一项很大的

  12. * 系统开销,为了高效的管理session,我们可以写一个监听器,定期清理掉过期的session

  13. */

  14. public class SessionScanerListener implements HttpSessionListener,ServletContextListener{

  15. // 创建一个线程安全的集合,用来存储session

  16. @SuppressWarnings("unchecked")

  17. List<HttpSession> sessionList = Collections.synchronizedList(new LinkedList<HttpSession>());

  18. private Object lock = new Object();

  19. public void sessionCreated(HttpSessionEvent httpSessionEvent) {

  20. System.out.println("session 创建成功...");

  21. HttpSession httpSession = httpSessionEvent.getSession();

  22. synchronized (lock){

  23. sessionList.add(httpSession);

  24. }

  25. }

  26. public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {

  27. System.out.println("session 销毁成功...");

  28. }

  29. // web应用关闭时触发contextDestroyed事件

  30. public void contextDestroyed(ServletContextEvent servletContextEvent) {

  31. System.out.println("web应用关闭...");

  32. }

  33. // web应用启动时触发contextInitialized事件

  34. public void contextInitialized(ServletContextEvent servletContextEvent) {

  35. System.out.println("web应用初始化...");

  36. // 创建定时器

  37. Timer timer = new Timer();

  38. // 每隔30秒就定时执行任务

  39. timer.schedule(new MyTask(sessionList,lock), 0, 1000*30);

  40. }

  41. }

 
  1. import java.util.List;

  2. import java.util.ListIterator;

  3. import java.util.TimerTask;

  4. import javax.servlet.http.HttpSession;

  5. /**

  6. * 定时器,定义定时任务的具体内容

  7. */

  8. public class MyTask extends TimerTask{

  9. private List<HttpSession> list;

  10. // 存储传递过来的锁

  11. private Object lock;

  12. // 构造方法

  13. MyTask(List<HttpSession> list, Object lock){

  14. this.list = list;

  15. this.lock = lock;

  16. }

  17. @Override

  18. public void run() {

  19. // 考虑到多线程的情况,这里必须要同步

  20. synchronized (lock){

  21. System.out.println("定时器开始执行...");

  22. ListIterator<HttpSession> listIterator = list.listIterator();

  23. while(listIterator.hasNext()){

  24. HttpSession httpSession = listIterator.next();

  25. // httpSession.getLastAccessedTime() = session的最后访问时间

  26. if(System.currentTimeMillis() - httpSession.getLastAccessedTime() > 1000*30){

  27. // 手动销毁session

  28. httpSession.invalidate();

  29. // 从集合中移除已经被销毁的session

  30. listIterator.remove();

  31. }

  32. }

  33. }

  34. }

  35. }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的监听器Listener)是一种广泛应用的设计模式,它用于处理程序中的事件。通过监听器,我们可以在事件发生时执行一些特定的操作。在Java中,我们可以使用内置的监听器API或自定义监听器实现此功能。 下面是Java中的常见监听器类型: 1. ActionListener:用于处理按钮、菜单等组件的动作事件。 2. WindowListener:用于处理窗口事件,如窗口打开、关闭等。 3. MouseListener:用于处理鼠标事件,如单击、双击、拖动等。 4. KeyListener:用于处理键盘事件,如键盘按下、释放等。 5. FocusListener:用于处理组件焦点事件,如获得或失去焦点等。 使用监听器的步骤如下: 1. 创建一个监听器类,该类实现了相应的监听器接口。 2. 在需要监听的组件上添加监听器对象。 3. 在监听器类中实现相应的方法来处理事件。 下面是一个简单的示例代码演示了如何使用ActionListener监听器处理按钮单击事件: ```java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ButtonListenerDemo implements ActionListener { private JFrame frame; private JButton button; public ButtonListenerDemo() { frame = new JFrame("Button Listener Demo"); button = new JButton("Click Me"); button.addActionListener(this); frame.getContentPane().add(button); frame.pack(); frame.setVisible(true); } public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(frame, "Button Clicked!"); } public static void main(String[] args) { new ButtonListenerDemo(); } } ``` 在上面的代码中,我们创建了一个ButtonListenerDemo类,该类实现了ActionListener接口。在构造函数中,我们创建了一个按钮对象,然后将该按钮添加到窗口中,并将该按钮的监听器设置为当前类。当用户单击按钮时,程序将调用actionPerformed()方法来处理事件,该方法将弹出一个消息框来告诉用户按钮已被单击。 总之,监听器Java编程中非常重要的组成部分。使用监听器,我们可以轻松地处理程序中的事件,并实现交互式用户界面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值