Servlet/ServletContextListener/ServletContextEvent 说明及使用

来源:互联网 发布:crf 算法 特征模板 编辑:程序博客网 时间:2024/06/07 12:11

实现 ServletContextListener 接口来设置应用共享参数/实现启动任务

在Spring项目中,很多初始化的工作都在后台悄悄完成,例如:初始化加载配置信息/数据等进入内存,或者开启后台任务等。具体是怎么实现的呢?

简单而言,都和 ServletContextListener 接口密切相关。它能监听 ServletContext 对象(web应用)的生命周期。当 Servlet 容器启动或者终止web应用时,会触发ServletContextEvent 事件。该事件由 ServletContextListener 处理,在ServletContextListener 接口中定义了处理该事件的两个方法:

//当Servlet容器终止web应用时调用该方法。在调用该方法之前,容器会先销毁所有的Servlet和Filter。void contextDestroyed(ServletContextEvent sce) /* Notification that the servlet context is about to be shut down. All servlets and filters have been destroyed before any ServletContextListeners are notified of context destorytion.*///当Servlet容器启动web应用时调用如下方法,调用后容器再初始化filter,并对需要被初始化的Servlet进行初始化。void contextInitialized(ServletContextEvent sce) /* Notification that the web application initialization process is starting. All ServletContextListeners are notified of context initialization before any filter or servlet in the web application is initialized.*/

容器 container 的四个子容器:Engine(每个service只能有1个)、Host、Context(代表一个应用程序or一个WEB-INF目录+其内的web.xml文件)、Wrapper。

javax.Servlet 包

包含描述和定义 servlet class 与 运行时环境之间(servlet容器提供给这个class实例)协定的类和接口。(The javax.servlet package contains a number of classes and interfaces that describe and define the contracts between a servlet class and the runtime environment provided for an instance of such a class by a conforming servlet container)

这里写图片描述

这里写图片描述

ServletContext 接口

这个接口定义一些 servlet 用来与 它的 servlet 容器通信的方法,例如:
getAttribute(); getContext(); getInitParameter(); getResource(); getServerInfo(); setAttribute(); log(java.lang.String msg)。
(Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file. )

ServletContext 对象

为整个web应用提供共享的内存,任何请求都可以访问里面的内容。是web容器(如tomcat)提供的全局上下文环境,为后面的Spring IOC容器提供宿主环境。

ServletContextListener 接口

这个接口的实现接收所在web应用 servlet context的改变通知
(Implementations of this interface receive notifications about changes to the servlet context of the web application they are part of.)

ServletContextEvent 类

web应用servlet context 改变的通知类
(This is the event class for notifications about changes to the servlet context of a web application.)

使用示例 1 - 服务启动时动态的加入 ServletContext 内容

1、StartInitListener 类实现 servletContextListerner 接口,将要共享的值通过传入的ServletContextEvent 的 getServletContext() 方法得到的 ServletContext,运行ServletContextEvent.setAttribute(key,value) 设置在内存中 ;

2、在项目的 \WEB-INF\web.xml 中配置监听器:

<listener>    <listener-class>com.testCompany.framework.StartInitListener</listener-class> </listener> 

3、项目通过ServletContext sct=getServletConfig().getServletContext(); sct.getAttribute(key) 将数据取到 。

使用示例 2 - 利用 contextDestroyed/contextInitialized 进行应用访问计数

1、方法 contextInitialized 在 Web 应用启动时从文件中读取计数器的数值,并设置在 ServletContext 中;
2、方法 contextDestroyed 在Web应用结束前从 ServletContext 获取计数器的数值,并写入文件 context.getRealPath(“/count”)。

使用示例 3 - 利用 contextDestroyed/contextInitialized + 配置文件生成实例存入 servletContext

public class Bootstrap implements ServletContextListener {     private ServletOAuthClient client;     @Override     public void contextInitialized(ServletContextEvent sce) {         client = new ServletOAuthClient();         ServletContext context = sce.getServletContext();         configureClient(context);         context.setAttribute(ServletOAuthClient.class.getName(), client);     }     @Override     public void contextDestroyed(ServletContextEvent sce) {         client.stop();     }     private void configureClient(ServletContext context) {         InputStream is = null;         String path = context.getInitParameter("keycloak.config.file");         if (path == null) {             is = context.getResourceAsStream("/WEB-INF/keycloak.json");         } else {             try {                 is = new FileInputStream(path);             } catch (FileNotFoundException e) {                 throw new RuntimeException(e);             }         }         client = ServletOAuthClientBuilder.build(is);     } }

使用示例 4 - 利用 contextDestroyed/contextInitialized + 配置文件生成实例启动后台线程

   private void executeConfig(ServletContextEvent context) {//      Properties pr = new Properties();      OrderProperties pr = new OrderProperties();        pr = PropertiesReader.getOrderProperties("startInit");        Iterator ite = pr.keySet().iterator();        while (ite.hasNext()) {            String clazz = pr.getProperty(ite.next().toString().trim());            int tagIndex = clazz.indexOf(PARAM_TAG);            String tag = "";            if(tagIndex != -1){                tag = clazz.substring(tagIndex+1,clazz.length());                clazz =  clazz.substring(0,tagIndex);            }            try {                if(!StringUtils.isEmpty(clazz)){                    Class c = Class.forName(clazz.trim());                    Object obj = c.newInstance();                    if (obj instanceof IStartInit) {                        if(tagIndex != -1){                            ((StartInit) obj).setParam(tag);                        }                        ((IStartInit) obj).execute(context);                    } else {                        throw new RuntimeException(clazz,e);                    }                }            } catch (Exception e) {                LOG.error(e.getMessage(), e);                throw new RuntimeException(clazz, e);            }        }    }

其它监听器(略)

ServletContextAttributeListener

监听对ServletContext属性的操作,比如增加、删除、修改属性。

HttpSessionListener

监听HttpSession的操作。当创建一个Session时,激发session Created(HttpSessionEvent se)方法;当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se)方法。

HttpSessionAttributeListener

监听HttpSession中的属性的操作。当在Session增加一个属性时,激发attributeAdded(HttpSessionBindingEvent se) 方法;当在Session删除一个属性时,激发attributeRemoved(HttpSessionBindingEvent se)方法;当在Session属性被重新设置时,激发attributeReplaced(HttpSessionBindingEvent se) 方法。

参考资料

http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContextListener.html
https://my.oschina.net/bayuanqian/blog/160073
http://www.programcreek.com/java-api-examples/index.php?api=javax.servlet.ServletContextEvent
http://www.cnblogs.com/mfc-itblog/p/5947945.html

0 0