Spring怎样注册Servlet、Filter、Listener组件
Servlet 3.0 之前,Servlet、Filter、Listener 这些组件都需要在 web.xml 中进行配置,3.0 之后开始不再需要 web.xml 这个配置文件了,所有的组件都可以通过代码配置或者注解来达到目的。
Servlet 3.0 开始提供了这 3 个注解来代替:
- @WebServlet:代替 servlet 配置
- @WebFilter:代替 filter 配置
- @WebListener:代替 listener 配置
注册Servlet组件
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 配置说明:
* name 名称,默认是类的全限定名称
* urlPatterns 指定url的匹配模式
* asyncSupported 是否支持异步操作
* initParams 指定初始化参数
*/
@WebServlet(name = "servletDemo", urlPatterns = "/servletDemo", asyncSupported = true,
initParams = {
@WebInitParam(name = "name", value = "servletDemo"),
@WebInitParam(name = "sex", value = "man") })
public class JavaServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String name = getServletConfig().getInitParameter("name");
String sex = getServletConfig().getInitParameter("sex");
resp.getOutputStream().println("name is " + name);
resp.getOutputStream().println("sex is " + sex);
System.out.println("---------servlet service----------");
}
}
@WebServlet 注解的属性:
属性名 | 类型 | 标签 | 描述 | 是否必需 |
---|---|---|---|---|
name | String | <servlet-name> | 指定 Servlet 的 name 属性。 如果没有显式指定,则取值为该 Servlet 的完全限定名,即包名+类名。 |
否 |
value | String[ ] | <url-pattern> | 该属性等价于 urlPatterns 属性,两者不能同时指定。 如果同时指定,通常是忽略 value 的取值。 |
是 |
urlPatterns | String[ ] | <url-pattern> | 指定一组 Servlet 的 URL 匹配模式。 | 是 |
loadOnStartup | int | <load-on-startup> | 指定 Servlet 的加载顺序。 | 否 |
initParams | WebInitParam[ ] | <init-param> | 指定一组 Servlet 初始化参数。 | 否 |
asyncSupported | boolean | <async-supported> | 声明 Servlet 是否支持异步操作模式。 | 否 |
description | String | <description> | 指定该 Servlet 的描述信息。 | 否 |
displayName | String | <display-name> | 指定该 Servlet 的显示名。 | 否 |
注册Filter组件
/**
* 配置说明
* filterName:过滤器名称
* urlPatterns:请求url的匹配模式
* initParams:初始化参数
*/
@WebFilter(filterName = "filterDemo", urlPatterns = "/*", initParams = {
@WebInitParam(name = "name", value = "filterDemo"),
@WebInitParam(name = "code", value = "123456") })
public class JavaFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("java filter init......start");
String name = filterConfig.getInitParameter("name");
String code = filterConfig.getInitParameter("code");
System.out.println("name is " + name);
System.out.println("code is " + code);
System.out.println("java filter init......end");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("java filter processing.doFilter");
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("java filter destroy.");
}
}
@WebServlet 注解的属性:
属性名 | 类型 | 描述 |
filterName | String | 指定过滤器的 name 属性,等价于 <filter-name> |
value | String[] | 该属性等价于 urlPatterns 属性。但是两者不应该同时使用。 |
urlPatterns | String[] | 指定一组过滤器的 URL 匹配模式。等价于 <url-pattern> 标签。 |
servletNames | String[] | 指定过滤器将应用于哪些 Servlet。取值是 @WebServlet 中的 name 属性的取值 |
注册Listener组件
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class ContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("listener...contextDestroyed");
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("listener...contextInitialized");
}
}
监听对象的创建与销毁
- HttpSessionListener:监听Session的创建与销毁。创建Session时执行sessionCreated(HttpSessionEvent se)方法。超时或者执行session.invalidate()时执行sessionDestroyed(HttpSessionEvent se)方法。该Listener可用于收集在线者信息。
- ServletContextListener:监听context的创建与销毁。context代表当前的web应用程序。服务器启动或者热部署war包时执行contextInitialiaed(ServletContextEvent event)方法。服务器关闭时或者只关闭该web时会执行contextDestroyed(ServletContextEvent event)方法。该Listener可用于启动时获取web.xml里配置的初始化参数。 ServletRequestListener:监听request的创建与销毁。用户每次请求request都会执行requestInitialized(ServletRequestEvent enent)方法。request处理完毕自动销毁前执requestDestroy(ServletRequestEvent event)方法。注意如果一个Html页面含有多个图片,则请求一次HTML页面可能会触发多次request事件。
监听对象的属性变化
这类Listener用于监听Session、context、request的属性的变化,接口方式为xxxAttributeListener,包括HttpAttributeListener、ServletContextListener、ServletRequestListener。当被监听对象中添加、更新、移除属性时,会分别执行xxxAdded(),xxxReplace(),xxxRemoved方法,xxx分别代表Session、context、request。
监听Session内的对象
除了上面的6种Listener,还有两种Listener用于监控Session内的对象,分别是HttpSessionBindingListener与HttpSessionActivationListener。
- HttpSessionBindingListener:当对象被放到Session里时执行valueBound(HttpSessionBindEvent event)方法。当对象被从Session里移除时执行valueUnbound(HttpSessionBindingEvent event)方法。
- HttpSessionActivationListener:当服务器关闭时,会将Session内容保存硬盘上,这个过程叫钝化,调用sessionWillPassivate(HttpSessionEvent se)方法,当对象被重新加载是,调用sessionDidActivate(HttpSessionEvent se)方法。
这两个Listener与上面的六种不同,这两个监听的是Session中的对象而非Session,所以不需要在web.xml中配置。
总结
Servlet、Listener、Filter的执行顺序:listener->Filter->servlet
简单记为:理(Listener)发(Filter)师(servlet)。
需要注意的是,为了安全考虑,内嵌服务器不会直接执行 Servlet 3.0 里面的 javax.servlet.ServletContainerInitializer 接口,或者 Spring 中的 org.springframework.web.WebApplicationInitializer 接口,否则会导致终止 Spring Boot 应用。
所以,如果使用的是 Spring Boot 内嵌服务器,需要在配置类上面添加额外的 @ServletComponentScan 注解来开启 Servlet 组件扫描功能,如果使用的是独立的服务器,则不需要添加,会使用服务器内部的自动发现机制。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现