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 组件扫描功能,如果使用的是独立的服务器,则不需要添加,会使用服务器内部的自动发现机制。

 

posted @   残城碎梦  阅读(204)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示