- 获取应用的初始化参数 (
web.xml中配置的) - 获取资源文件 (如
properties,xml) - 在应用范围内存取属性 (
setAttribute,getAttribute) - 获取 MIME 类型
- 获取服务器信息等
获取 ServletContext 的方法有很多种,具体取决于你所在的代码环境(在 Servlet 中、在 Filter 中、在 Spring 管理的 Bean 中等)。

下面我将为你详细介绍几种最常见和重要的方法。
在原生 Servlet / Filter 中获取 (最直接)
这是最基础也是最直接的方法,在 Servlet API 中,ServletConfig 和 ServletRequest 对象都提供了获取 ServletContext 的方法。
通过 ServletConfig 获取
每个 Servlet 在初始化时都会收到一个 ServletConfig 对象,它包含了该 Servlet 的配置信息,并且可以通过 getServletContext() 方法获取 ServletContext。
示例代码:

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1. 通过 this.getServletContext() 获取 (推荐)
// this 指代当前的 Servlet 实例,Servlet 实现了 ServletConfig 接口
ServletContext application = this.getServletContext();
// 2. 或者通过 request.getServletContext() 获取 (Servlet 3.0+)
// ServletContext application = request.getServletContext();
// 使用 application
String appInitParam = application.getInitParameter("appParam"); // 获取应用初始化参数
application.setAttribute("myAttribute", "Hello from Servlet!"); // 设置应用属性
response.getWriter().println("ServletContext obtained via ServletConfig!");
}
}
通过 HttpServletRequest 获取
从 Servlet 3.0 开始,HttpServletRequest 对象直接提供了 getServletContext() 方法,这使得在任何可以拿到 request 对象的地方都能方便地获取 ServletContext。
示例代码 (在 Filter 中):
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 将 ServletRequest 转换为 HttpServletRequest (通常需要)
HttpServletRequest httpRequest = (HttpServletRequest) request;
// 通过 request 对象获取 ServletContext
ServletContext application = httpRequest.getServletContext();
// 使用 application...
System.out.println("Filter got ServletContext: " + application.getContextPath());
// 继续执行过滤器链
chain.doFilter(request, response);
}
// ... 其他 Filter 方法
}
在 Spring/Spring Boot 中获取 (最常用)
在现代 Spring 应用中,获取 ServletContext 的方式更加灵活和多样化。
通过依赖注入 (Dependency Injection) - 推荐
Spring 容器会管理 ServletContext 的生命周期,你可以直接将它作为一个 Bean 注入到任何 Spring 管理的组件(如 @Controller, @Service, @Component)中。

示例代码 (Spring MVC):
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.ServletContext;
@Controller
public class MyController {
// 通过构造器注入 (推荐方式)
private final ServletContext servletContext;
// Spring 会自动注入 ServletContext 实例
public MyController(ServletContext servletContext) {
this.servletContext = servletContext;
}
@GetMapping("/get-context")
@ResponseBody
public String getServletContext() {
// 使用注入的 servletContext
String realPath = servletContext.getRealPath("/WEB-INF/");
return "ServletContext obtained via DI! RealPath: " + realPath;
}
// 或者通过 Setter 注入
/*
@Autowired
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
*/
}
通过 WebApplicationContextUtils 获取
如果你在一个非 Spring 托管的类(一个工具类、一个监听器或一个第三方库的回调中)需要获取 ServletContext,可以通过 WebApplicationContextUtils 来获取 Spring 的 WebApplicationContext,然后从中获取 ServletContext。
示例代码 (工具类中):
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletContext;
public class MyUtil {
public static void doSomething(ServletContext servletContext) {
// 从 ServletContext 获取 Spring 的根应用上下文
WebApplicationContext webAppContext =
WebApplicationContextUtils.getWebApplicationContext(servletContext);
if (webAppContext != null) {
// 现在你可以获取 Spring 容器中的任何 Bean
MyService myService = webAppContext.getBean(MyService.class);
myService.performTask();
}
}
}
通过 ServletContextAware 接口 - 不推荐,但可行
让你的组件实现 ServletContextAware 接口,Spring 会在初始化时自动调用 setServletContext 方法,这种方式侵入性较强,耦合度较高,通常不推荐使用,除非有特殊需求。
import org.springframework.stereotype.Component;
import org.springframework.web.context.ServletContextAware;
import javax.servlet.ServletContext;
@Component
public class MyComponent implements ServletContextAware {
private ServletContext servletContext;
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
public void useContext() {
// ...
}
}
通过监听器 (Listener) 获取
ServletContextListener 是一个 Servlet API 中的监听器,它会在 Web 应用启动和销毁时被通知,这是获取 ServletContext 的一个绝佳位置,尤其适合用于执行应用启动时的初始化任务。
示例代码:
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class MyContextListener implements ServletContextListener {
// 在应用启动时调用
@Override
public void contextInitialized(ServletContextEvent sce) {
// 通过 sce.getServletContext() 获取
ServletContext application = sce.getServletContext();
System.out.println("Application started! Context path: " + application.getContextPath());
// 加载初始化数据
String initDataPath = application.getInitParameter("initDataPath");
System.out.println("Loading data from: " + initDataPath);
}
// 在应用关闭时调用
@Override
public void contextDestroyed(ServletContextEvent sce) {
ServletContext application = sce.getServletContext();
System.out.println("Application shutting down...");
// 清理资源
}
}
总结与最佳实践
| 场景 | 推荐方法 | 说明 |
|---|---|---|
| 原生 Servlet | this.getServletContext() 或 request.getServletContext() |
最直接,Servlet API 内置支持。 |
| 原生 Filter | request.getServletContext() |
简单直接,Servlet 3.0+ 后可用。 |
| Spring 管理的 Bean | 依赖注入 (@Autowired 或构造器) |
最佳实践,代码解耦,易于测试。 |
| Spring 非托管类 | WebApplicationContextUtils.getWebApplicationContext(servletContext) |
在无法使用 DI 时,通过 ServletContext 桥接到 Spring 容器。 |
| 应用初始化 | ServletContextListener |
专门用于监听应用生命周期,是执行启动任务的理想位置。 |
核心要点:
ServletContextapplication:在 Java Web 开发中,我们常说的application作用域,其底层实现就是ServletContext。- 选择合适的方法:根据你代码的运行环境(原生 vs Spring,托管 vs 非托管)选择最合适的获取方式。
- 优先使用依赖注入:在 Spring 生态中,始终优先考虑使用依赖注入来获取
ServletContext,这会使你的代码更干净、更易于维护和测试。
