ServletContext
AServletContext表示您的整个 Web 应用程序在 Servlet 容器中运行。正如Servlet 规范所承诺的,在 servlet 处理第一个 HTTP 请求之前建立上下文。虽然 aHttpSession代表每个用户的工作会话(从技术上讲,是通过您的 servlet 代码的线程),但 aServletContext代表所有这些用户的范围。
要挂钩到 servlet 上下文的设置和拆卸,请实现一个ServletContextListener. @WebListener提示:通过使用注释标记它来自动部署您的侦听器。该接口需要一对方法,在处理第一个 Servlet 请求之前设置 Web 应用程序以及拆除 Web 应用程序时调用每个方法。
提示:这种拆卸方法是关闭您的ScheduledExecutorService. 与您的执行程序服务关联的线程可能会在您的 Web 应用程序结束后继续存在。您可能不希望这种情况发生。
看到这个问题:How to get and set a global object in Java servlet context
另请参阅BalusC对 Servlet 范围的精彩总结。
获取 servlet 上下文
您可以通过首先访问当前 servletServletContext来访问其ServletConfig.
// … in your Servlet, such as its request handler methods like `doGet` …
ServletContext sc = this.getServletConfig().getServletContext() ;
那么在 aServletContextListener中,我们如何访问 servlet 上下文呢?当调用侦听器上的两个方法中的任何一个时,都会传递一个ServletContextEvent 。从那里打电话ServletContextEvent::getServletContext()。
在 servlet 上下文中将对象存储为“属性”
那么在哪里存储你的网络应用程序的全局变量,比如你的ScheduledExecutorService?Stringservlet 上下文有一个to的内置映射Object。这些被称为“属性”。调用setAttribute( String , Object )以存储属性映射。因此,为您ScheduledExecutorService在此地图中使用密钥起一个名称。
ScheduledExecutorService sec = … ; // Instantiated somewhere in your code.
…
String key = "myScheduledExecutorServiceForXYZ" ;
sc.setAttribute( key , sec ); // Storing the executor service as a generic `Object` for use later.
稍后您可以ScheduledExecutorService以相同的方式获取您的。在这种情况下,您将需要转换Object为已知类ScheduledExecutorService。
Object o = sc.getAttribute( key ); // Fetch the `ScheduledExecutorService` from the servlet context’s built-in map of attributes.
// Cast to known class. If in doubt, test first with [`instanceOf`][11].
ScheduledExecutorService sec = ( ScheduledExecutorService ) o ;
您可以通过调用来请求所有存储的属性名称的列表ServletContext::getAttributeNames。
范围图
这是我的一个图表,用于了解 Servlet 环境中的范围层次结构。注意范围的每一层都有它的属性集,它自己的Stringto映射Object。沿着图表向下看,每组属性的生命周期都较短。
