监听器就是一个实现特定接口的普通
java
程序,这个程序专门用于监听另一个
java
对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
监听器典型案例:监听
window
窗口的事件监听器
1 事件三要素
a)事件源:操作事件的对象,例如:窗体Frame
b)事件监听器:事件监听器监听事件源,例如WindowListner,它是一个接口
c)事件,例如:单击事件,通过事件,可以取得事件源
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class Demo1 {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setSize(550, 400);
frame.setLocation(250, 250);
frame.setVisible(true);
// 添加监听事件【事件监听器监听事件源】
frame.addWindowListener(new WindowAdapter() {//3、内部类
public void windowClosing(WindowEvent e) {
//super.windowClosing(e);
System.exit(0);
}
});
}
}
// 2、继承WindowAdapter--适配器
/*class MyWindowListener extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
//super.windowClosing(e);
System.exit(0);
}
}*/
//1、实现接口-- WindowListener-事件监听器
/*class MyWindowListener implements WindowListener{
public void windowOpened(WindowEvent e) {
}
public void windowClosing(WindowEvent e) {
// 取得事件源
Frame frame = (Frame) e.getSource();
// 将事件源隐藏
// frame.setVisible(false);
// 将jvm强行终止
System.exit(0);//0表示正常终止,1表示强行终止
System.out.println("windowClosing()...");
}
public void windowClosed(WindowEvent e) {
System.out.println("windowClosed()");
}
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowActivated(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e) {
}
}*/
适配器模式
a)当一个接口有较多的方法时,而实现类只需对其中少数几个实现,此时可以使用适配器模式
b)适配器模式常用于GUI编程
Servlet监听器
在Servlet规范中定义了多种类型的监听器,它们用于监听的事件源分别为
ServletContext,
HttpSession 和
ServletRequest 这三个域对象
Servlet规范针对这三个对象上的操作,又把这多种类型的监听器划分为三种类型。
•监听三个域对象创建和销毁的事件监听器
•监听域对象中属性的增加和删除的事件监听器
•监听绑定到HttpSession 域中的某个对象的状态的事件监听器。(查看API文档)
1、监听ServletContext域对象创建和销毁
ServletContextListener
接口用于监听
ServletContext
对象的创建和销毁事件。
当
ServletContext
对象被创建时,激发
contextInitialized
(
ServletContextEvent
sce
)
方法
当 ServletContext对象被销毁时,激发contextDestroyed(ServletContextEventsce)方法。
ServletContext
域对象何时创建和销毁?
•创建:服务器启动针对每一个web应用创建ServletContext
•销毁:服务器关闭前先关闭代表每一个web应用的ServletContext
监听器的工作过程和生命周期
和编写其它事件监听器一样,编写servlet监听器也需要实现一个特定的接口,并针对相应动作覆盖接口中的相应方法。
和其它事件监听器略有不同的是,servlet监听器的注册不是直接注册在事件源上,而是由web容器负责注册,开发人员只需在web.xml文件中使用<listener>标签配置好监听器,web容器就会自动把监听器注册到事件源中。
一个 web.xml 文件中可以配置多个 Servlet 事件监听器,web 服务器按照它们在 web.xml 文件中的注册顺序来加载和注册这些 Serlvet 事件监听器。
开发过程:
a)写一个普通类实现对应的接口,即事件监听器
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
//事件监听器[用于监听ServletContext对象产生和销毁]
public class MyServletContextListener implements ServletContextListener{
public MyServletContextListener(){
System.out.println("空参构造");
System.out.println(this.hashCode());
}
//产生
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext产生");
System.out.println(this.hashCode());
}
//销毁
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext销毁");
System.out.println(this.hashCode());
}
}
b)在web.xml文件中注册事件监听器
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!--事件源注册事件监听器-->
<listener>
<listener-class>cn.zengfansheng.web.listener.MyServletContextListener</listener-class>
</listener>
</web-app>
练习:
创建系统的所有表结构和数据,即初始化工作-每x秒向数据库中插入一条记录
1)写一个普通类实现对应的接口,即事件监听器
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import cn.itcast.web.dao.SystemDao;
public class SystemListener implements ServletContextListener {
private Timer timer = new Timer();
public void contextInitialized(ServletContextEvent sce) {
try {
SystemDao systemDao = new SystemDao();
systemDao.createTable("systemInit");
timer.schedule(new SystemTask(),0,5*1000);
} catch (Exception e) {
}
}
public void contextDestroyed(ServletContextEvent sce) {
try {
SystemDao systemDao = new SystemDao();
systemDao.dropTable("systemInit");
//中止定时器
timer.cancel();
} catch (Exception e) {
}
}
}
//任务类
class SystemTask extends TimerTask{
public void run() {
try {
SystemDao systemDao = new SystemDao();
systemDao.init("systemInit",UUID.randomUUID().toString());
} catch (Exception e) {
}
}
}
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import cn.itcast.web.util.JdbcUtil;
public class SystemDao {
//删除表
public void dropTable(String tableName) throws SQLException{
QueryRunner runner = new QueryRunner(JdbcUtil.getDataSource());
String sql = "drop table if exists " + tableName;
runner.update(sql);
}
//创建表
public void createTable(String tableName) throws SQLException{
QueryRunner runner = new QueryRunner(JdbcUtil.getDataSource());
String sql = "create table if not exists "+tableName+"(id varchar(40) primary key,curr_time timestamp not null)";
runner.update(sql);
}
//初始化数据
public void init(String tableName,String id) throws SQLException{
QueryRunner runner = new QueryRunner(JdbcUtil.getDataSource());
String sql = "insert into "+tableName+"(id) values(?)";
runner.update(sql,id);
}
}
2)在web.xml文件中注册事件监听器
<listener>
<listener-class>cn.zengfansheng.web.listener.SystemListener</listener-class>
</listener>
c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/mydb3</property>
</default-config>
</c3p0-config>
2、监听ServletRequest域对象创建和销毁
ServletRequestListener
接口用于监听
ServletRequest
对象的创建和销毁。
Request
对象被创建时,监听器的
requestInitialized
方法将会被调用。
Request
对象被销毁时,监听器的
requestDestroyed
方法将会被调用。
servletRequest域对象创建和销毁的时机:
•创建:用户每一次访问,都会创建一个reqeust
•销毁:当前访问结束,request对象就会销毁