Servlet/ServletContextListener/ServletContextEvent 说明及使用

2 篇文章 0 订阅
1 篇文章 0 订阅
实现 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

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值