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());
    }
}

 

参考文章

【1】过滤器和拦截器的使用及其区别

【2】SpringBoot事件监听机制

posted @ 2023-02-27 15:34  先娶国王后取经  阅读(94)  评论(0编辑  收藏  举报