拦截器、过滤器、监听器
过滤器和拦截器之间的关系
- 拦截器是基于Java的反射机制的,而过滤器是基于函数回调
- 拦截器依赖于spring容器,只作用于SpringMVC控制的请求;
- 过滤器依赖于servlet容器,作用于所有Servlet请求;即作用范围更大


过滤器
@Slf4j
@Component
@WebFilter(urlPatterns = {"/*"})
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
log.info("[过滤器] 初始化");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 1. 预处理逻辑(在调用 chain.doFilter 之前)
System.out.println("【预处理】请求到来:" + ((HttpServletRequest)request).getRequestURI());
// 2. 调用下一个过滤器或目标资源(如 Controller)
chain.doFilter(request, response);
// 3. 后处理逻辑(在调用 chain.doFilter 之后)
System.out.println("【后处理】响应返回:" + ((HttpServletRequest)request).getRequestURI());
}
@Override
public void destroy() {
Filter.super.destroy();
log.info("【过滤器】销毁");
}
}
// 假如你有两个过滤器A和B,顺序A在外,B在内
// Filter A
doFilter(...) {
System.out.println("A 前置");
chain.doFilter(request, response); // 回调到下一个过滤器B
System.out.println("A 后置");
}
// Filter B
doFilter(...) {
System.out.println("B 前置");
chain.doFilter(request, response); // 回调到 Controller
System.out.println("B 后置");
}
// 最终执行流程如下
A 前置
B 前置
Controller 处理
B 后置
A 后置
注册过滤器
1、使用注解@WebFilter:urlPatterns属性配置了哪些请求可以进入该过滤器,/*表示所有请求;
2、使用FilterRegistrationBean
public class TimeFilterConfig {
@Bean
public FilterRegistrationBean timeFilter() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
TimeFilter timeFilter = new TimeFilter();
filterRegistrationBean.setFilter(timeFilter);
List<String> urlList = new ArrayList<>();
urlList.add("/*");
filterRegistrationBean.setUrlPatterns(urlList);
return filterRegistrationBean;
}
}
拦截器
@Slf4j
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("【拦截器】处理前");
request.setAttribute("startTime", System.currentTimeMillis());
log.info(((HandlerMethod) handler).getBean().getClass().getName());
// true表示放行,false表示拦截
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("【拦截器】处理中");
Long start = (Long) request.getAttribute("startTime");
log.info("【拦截器】耗时:" + (System.currentTimeMillis() - start)+"ms");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
log.info("【拦截器】处理后");
Long start = (Long) request.getAttribute("startTime");
log.info("【拦截器】耗时:" + (System.currentTimeMillis() - start)+"ms");
}
}
注册拦截器
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
@Override
protected void addInterceptors(InterceptorRegistry registry) {
//addPathPatterns指定拦截器要拦截的路径
//excludePathPatterns指定拦截器不拦截的路径
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/index/**");
}
}
监听器
- 使用ApplicationContext发布事件
- 使用@EventListener监听事件
自定义事件
@Getter
@Setter
public class UserRegisterEvent extends ApplicationEvent {
private User user;
public UserRegisterEvent(Object source, User user) {
super(source);
this.user = user;
}
}
发布事件
@Service
public class UserServiceImpl implements UserService {
@Autowired
private ApplicationContext applicationContext;
public void register(User user)
{
// 发布事件
applicationContext.publishEvent(new UserRegisterEvent(this, user));
System.out.println("用户注册成功");
}
public void sendMail(Email Email)
{
// 发布事件
applicationContext.publishEvent(new UserMailEvent(this, Email));
System.out.println("邮件发送成功");
}
}
监听事件
通过注解监听事件
@Component
public class MyRegisterListener {
@EventListener(UserRegisterEvent.class)
public void onApplicationEvent(UserRegisterEvent event)
{
System.out.println("监听到事件:" + event.getUser().getUsername());
}
@EventListener(UserMailEvent.class)
public void onApplicationEvent(UserMailEvent event)
{
System.out.println("监听到事件(@EventListener监听):" + event.getEmail().getSender());
}
}
通过ApplicationListener监听事件
@Component
public class UserEmailListener implements ApplicationListener<UserMailEvent> {
@Override
public void onApplicationEvent(UserMailEvent event) {
System.out.println("监听到事件(ApplicationListener接口):" + event.getEmail().getSender());
}
}

浙公网安备 33010602011771号