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

浙公网安备 33010602011771号