SpringBoot 拦截器、过滤器、监听器
过滤器和拦截器之间的关系
- 拦截器是基于Java的反射机制的,而过滤器是基于函数回调
- 拦截器依赖于spring容器,过滤器依赖于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 servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("【过滤器】开始执行");
Long startTime = System.currentTimeMillis();
filterChain.doFilter(servletRequest, servletResponse);
log.info("【过滤器】耗时:" + (System.currentTimeMillis() - startTime)+"ms");
log.info("【过滤器】结束执行");
}
@Override
public void destroy() {
Filter.super.destroy();
log.info("【过滤器】销毁");
}
}
注册方式
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;
}
}
拦截器
实现HandlerInterceptor接口
@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());
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!