目录
大佬文章,请优先查看!!!
【SpringBoot】SpringBoot 过滤器、监听器、拦截器、AOP 比较
拦截器概念
拦截器(Interceptor)是Spring MVC 框架提供的一种机制,它可以在请求处理的过程中对请求和响应进行拦截和处理。拦截器可以在请求到达目标处理器之前、处理器处理请求之后以及视图渲染之前执行特定的操作。拦截器的主要目的是在不修改原有代码的情况下,实现对请求和响应的统一处理。
拦截器的作用
权限控制:拦截器可以在请求到达处理器之前进行权限验证,从而实现对不同用户的访问控制。
日志记录:拦截器可以在请求处理过程中记录请求和响应的详细信息,便于后期分析和调试。
接口幂等性校验:拦截器可以在请求到达处理器之前进行幂等性校验,防止重复提交。
数据校验:拦截器可以在请求到达处理器之前对请求数据进行校验,确保数据的合法性。
缓存处理:拦截器可以在请求处理之后对响应数据进行缓存,提高系统性能。
应用场景
认证与授权:拦截器可以用于实现认证和授权的逻辑,例如检查用户是否登录、验证用户权限等。在进入具体的控制器方法之前,通过拦截器可以拦截未经认证或未授权的请求。
日志记录:拦截器可以用于记录请求的相关日志信息,如请求的 URL、请求参数、处理时间等。通过拦截器,在请求进入控制器方法之前或之后,可以将这些信息进行记录,方便后续的日志分析和监控。
异常处理:拦截器可以捕获控制器方法中抛出的异常,并进行相应的处理,如统一的异常封装、返回错误信息等。通过拦截器,可以实现对异常的集中处理,避免在每个控制器方法中都进行异常处理的重复代码。
参数预处理:拦截器可以对请求的参数进行预处理,如参数的验证、格式转换等。通过拦截器,可以在进入控制器方法之前对请求参数进行统一的处理,减少控制器方法中的参数处理逻辑。
缓存控制:拦截器可以用于对响应进行缓存的控制,例如在满足一定条件时,直接返回缓存的响应,减少服务器的压力。通过拦截器,可以实现自定义的缓存策略,灵活地控制缓存的生效条件。
需要注意的是,拦截器是 Spring MVC 框架特有的概念,并且只对控制器层起作用,不会影响到其他层的业务逻辑。拦截器与过滤器(Filter)相比,更加专注于请求处理和控制器层面的操作。
总结起来,拦截器适用于对请求进行拦截、预处理和后处理的场景,包括认证与授权、日志记录、异常处理、参数预处理和缓存控制等。通过拦截器,可以实现灵活的请求处理逻辑,提高代码的可维护性和可重用性。
实际开发中确实更常见使用过滤器(Filter),而拦截器(Interceptor)使用的场景相对较少。这主要是因为过滤器和拦截器在功能上存在一些区别,适用于不同的需求。
过滤器(Filter)是基于 Servlet 规范的一种机制,可以对请求进行过滤、修改和拦截处理。它工作在请求进入框架之前,可以对所有请求进行统一处理,例如字符编码设置、认证与授权、日志记录等。过滤器是在整个请求的生命周期中起作用,可以对请求进行全局性的预处理和后处理。由于过滤器是在底层框架之前调用的,它具有更高的优先级,可以在请求到达框架之前拦截请求。
拦截器更专注于控制器层面的操作,可以对请求进行细粒度的拦截和处理。
虽然拦截器使用的场景相对较少,但在某些需要对请求进行精细控制的情况下,拦截器可以提供更灵活和可扩展的功能。比如针对某一类请求需要特殊处理、需要记录请求处理时间等,这样的场景更适合使用拦截器来实现。
综上所述,过滤器和拦截器各有其特点,在实际开发中根据具体需求选择使用哪种机制,或者结合使用两者来满足不同的业务需求。过滤器更加通用且功能强大,而拦截器更加专注于控制器层面的处理。
SpringBoot中的拦截器实现
实现HandlerInterceptor接口
要在SpringBoot中实现拦截器,首先需要创建一个类并实现HandlerInterceptor接口。HandlerInterceptor接口包含以下三个方法:
方法名称 | 说明 |
---|---|
preHandle | 在请求到达处理器之前执行,可以用于权限验证、数据校验等操作。如果返回true,则继续执行后续操作;如果返回false,则中断请求处理。 |
postHandle | 在Controller处理器处理请求之后执行,可以用于日志记录、缓存处理等操作。 |
afterCompletion | 在 DispatcherServlet 渲染了对应的视图之后执行,可以用于资源清理等操作。 |
以下是一个简单的拦截器实现示例:
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
System.out.println("preHandle: " + request.getRequestURI());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
System.out.println("postHandle: " + request.getRequestURI());
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
System.out.println("afterCompletion: " + request.getRequestURI());
}
}
注册拦截器到InterceptorRegistry
要让拦截器生效,需要将其注册到InterceptorRegistry
中。这可以通过实现WebMvcConfigurer
接口并重写addInterceptors
方法来实现。以下是一个简单的注册示例:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor());
}
}
配置拦截器的拦截规则
在注册拦截器时,可以通过addPathPatterns
和excludePathPatterns
方法来配置拦截器的拦截规则。addPathPatterns
方法用于指定需要拦截的请求路径,excludePathPatterns
方法用于指定不需要拦截的请求路径。以下是一个配置示例:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login", "/register")
// 当有多个拦截器order(序号)控制执行先后顺序,序号越小越先执行
.order(1);
}
}
在上述示例中,我们配置了拦截器拦截所有请求,但排除了登录和注册请求。
拦截器的执行顺序和生命周期
拦截器的执行顺序
当有多个拦截器时,它们的执行顺序取决于注册顺序。先注册的拦截器先执行,后注册的拦截器后执行。在请求处理过程中,拦截器的preHandle方法按注册顺序执行,而postHandle和afterCompletion方法按注册顺序的逆序执行。
拦截器的生命周期
拦截器的生命周期由Spring容器管理。当Spring容器启动时,拦截器会被实例化并初始化;当Spring容器关闭时,拦截器会被销毁。
多个拦截器的执行流程
当有多个拦截器时,它们的执行流程如下:
1、执行所有拦截器的preHandle方法,按注册顺序执行。如果某个拦截器的preHandle方法返回false,则中断请求处理,直接执行已执行拦截器的afterCompletion方法。
2、执行处理器的处理方法。
3、执行所有拦截器的postHandle方法,按注册顺序的逆序执行。
4、渲染视图。
5、执行所有拦截器的afterCompletion方法,按注册顺序的逆序执行。
拦截器的性能优化和常见问题
拦截器在请求处理过程中可能会影响系统性能,以下是一些性能优化策略:
减少拦截器数量:尽量将相关功能集中到一个拦截器中,避免创建过多的拦截器。
精确配置拦截规则:通过addPathPatterns和excludePathPatterns方法精确配置拦截规则,避免不必要的拦截。
使用异步处理:在拦截器中使用异步处理,避免阻塞请求处理过程。
使用缓存:在拦截器中使用缓存,减少对数据库或其他资源的访问。
拦截器的常见问题和解决方案
在实际使用过程中,我们可能会遇到一些问题,如拦截器不生效、执行顺序错误或影响性能等。
拦截器不生效:拦截器不生效的可能原因有很多,其中最常见的包括拦截器未注册到InterceptorRegistry
、拦截规则配置错误等。
为了解决这个问题,我们需要首先检查拦截器是否已经正确注册到InterceptorRegistry
中,然后再检查拦截规则是否配置正确。如果发现问题,需要及时进行调整和修复。
拦截器执行顺序错误:拦截器执行顺序错误的主要原因是拦截器的注册顺序错误。在实际应用中,拦截器的执行顺序是根据它们在InterceptorRegistry
中的注册顺序来决定的。因此,为了解决这个问题,我们需要调整拦截器在InterceptorRegistry
中的注册顺序,确保它们按照预期的顺序执行。
拦截器影响性能:拦截器影响性能的主要原因是拦截器中的处理逻辑过于复杂或资源消耗过大。为了解决这个问题,我们需要对拦截器的处理逻辑进行优化,尽量减少不必要的计算和资源消耗。同时,我们还可以考虑使用一些性能监控工具,如JProfiler等,来对拦截器的性能进行实时监控和分析,从而找到性能瓶颈并进行优化。
拦截器与过滤器的区别
1.运行顺序不同
执行顺序:过滤器在拦截器之前执行,拦截器在处理器之前执行。
2.配置方式不同
过滤器在web.xml配置(注解)
拦截器在spring配置文件中(注解)
3.依赖不同
Filter依赖Servlet容器,由Servlet容器管理。
Interceptor不依赖Servlet容器,拦截器由Spring容器管理。
4.操作对象不同
Filter可以操作request、response。Filter对所有访问进行增强(在Tomcat服务器进行配置)。
Interceptor可以操作request、response、handler、modeAndView、exception,可以操作spring中组件。Interceptor仅针对SpringMVC的访问进行增强。
5.使用场景不同
过滤器适用于对请求和响应的全局处理,拦截器适用于对特定请求的处理。
标签:拦截器,SpringBoot,处理,顺序,过滤器,执行,请求 From: https://www.cnblogs.com/leizia/p/18079242