文章目录
监听器接口
监听器接口简介
介绍
- 一组(8个)来自于servlet规范中
- 监听器接口由项目开发人员负责实现
- 监听器负责监听作用域对象并在指定事件中调用监听处理方法
作用域对象
存在于服务端计算机内存中,可以在指定条件下为Servlet之间提供数据共享服务的对象(由于Cookie存在于客户端浏览器中,所以不包含Cookie)
Servlet规范中定义的作用域对象(三个)
- ServletContext接口 — 全局作用域对象
- HttpSession接口 — 会话作用域对象
- HttpServletRequest — 请求作用域对象
监听器作用
- 监听作用域对象生命周期变化时刻
- 监听作用域对象存放共享数据变化时刻
监听器接口实现类开发步骤
- 根据监听目的选择对应的接口进行实现
- 重写监听器接口中的事件处理方法,这些方法在指定事件产生时由Tomcat负责调用
- web.xml向Tomcat注册监听器接口实现类
ServletContextListener接口
介绍
监听【全局作用域对象】的生命周期变化时刻
全局作用域对象生命周期 🔺
- 在Tomcat启动时,自动为当前网站创建全局作用域对象
- 在Tomcat运行时,一个网站有且只能由一个全局作用域对象
- 在Tomcat关闭时,自动销毁网站中的全局作用域对象
(声明周期贯穿整个网站的运行期间)
ServletContextAttributeListener接口
介绍
监听【全局作用域对象】共享数据变化时刻
全局作用域对象共享数据变化
ServletContext application = request.getServletContext();
applicatoin.setAttribute("key1",100); //新增共享数据
applicatoin.setAttribute("key1",200); //更新共享数据
applicatoin.removeAttribute("key1",100); //移除共享数据
监听器应用场景
数据库连接池
需求引入:
在部门管理项目中,通过(end.getTime()-start.getTime())可以得知在整个过程中,JDBC规范Connection创建与销毁最耗时。为了对其进行优化,引入数据库连接池。
分析数据库连接池(Connection)
- 在Tomcat启动时,预先创建一定数量的Connection
- 在Tomcat运行时,为用户提供服务时选择一个空闲的Connection为用户使用
- 在Tomcat运行时,用户服务处理完毕后不会销毁Connection,而是将其重新设置为空闲状态
- 在Tomcat准备关闭时,销毁所有的Connection
实施障碍
- 如何确保连接通道在Tomcat运行时一直存在(全局作用域对象)
- 如何将连接通道共享给所有的Servlet(全局作用域对象)
- 如何知晓Tomcat何时启动与何时关闭(ServletContextListener)
监听器的具体实现
public class PoolListener implements ServletContextListener {
//在Tomcat启动时,预先创建一定数量的Connection
@Override
public void contextInitialized(ServletContextEvent sce) {
JdbcUtil util = new JdbcUtil();
Map map = new ConcurrentHashMap();
for (int i = 0; i < 20; i++) {
Connection con = util.getCon();
// System.out.println("启动时创建Connection:" + con);
map.put(con, true); //true表示连接通道Connection空闲状态
}
ServletContext servletContext = sce.getServletContext();
servletContext.setAttribute("pool", map);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
Map map = (ConcurrentHashMap) servletContext.getAttribute("pool");
Iterator iterator = map.keySet().iterator();
while (iterator.hasNext()) {
Connection con = (Connection) iterator.next();
if (con != null) {
System.out.println("Connection " + con + " 被销毁");
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}