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
?String
servlet 上下文有一个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 环境中的范围层次结构。注意范围的每一层都有它的属性集,它自己的String
to映射Object
。沿着图表向下看,每组属性的生命周期都较短。