掌握springboot过滤器,拦截器 ,aop
前言:
Spring Boot 中的过滤器(Filter)、拦截器(Interceptor)和 AOP(面向切面编程)都是处理请求的常用技术,但它们在处理请求的时机、范围和方式上有所不同。下面详解分别介绍:
执行顺序:过滤器->拦截器->aop
1. 过滤器(Filter)
过滤器是一个标准的Java规范,它在请求进入Servlet之前或者响应离开Servlet之后对请求或响应进行拦截处理。过滤器可以应用于整个Web应用程序,并且可以对请求和响应进行预处理或后处理;例如可以提前过滤一些信息或者提前设置一些参数,再或者过滤一些非法url,过滤敏感词。
原理:依赖Servlet容器,基于函数回调实现。
应用场景:
-
日志记录
-
登录校验,权限校验
-
防御XSS攻击
-
请求内容修改
-
响应内容修改
使用步骤:
@Component
@WebFilter
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("TestFilter过滤器------>初始化先执行");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 在请求处理之前进行调用(如登录检查)
System.out.println("TestFilter过滤器------>进入web容器之前");
// 继续过滤器链中的下一个过滤器
chain.doFilter(request, response);
// 在请求处理之后进行调用(如日志记录)
System.out.println("TestFilter过滤器------>进入web容器之前");
}
@Override
public void destroy() {
System.out.println("TestFilter过滤器------>最后执行");
}
}
2. 拦截器(Interceptor)
拦截器是基于Spring框架,用于在请求的前后进行拦截处理。拦截器只作用于Spring管理的Bean,因此它不能拦截静态资源或者非Spring MVC处理的请求。
原理:依赖于Spring框架,是aop的一种表现,基于Java的动态代理实现的。
应用场景:
-
登录校验,权限验证,签名验证
-
日志记录
-
请求参数修改
-
响应结果修改
使用步骤:
- 声明拦截器的类:1.通过实现 HandlerInterceptor接口;2,继承HandlerInterceptorAdapter类; 实现preHandle、postHandle和afterCompletion方法。
@Component
public class TestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 在请求处理之前进行调用(如权限检查)
System.out.println("TestInterceptor拦截器在请求处理之前进行调用");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
// 请求处理之后进行调用,但在视图被渲染之前(如修改模型和视图)
System.out.println("TestInterceptor拦截器请求处理之后进行调用");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// 在整个请求结束之后被调用(如日志记录)
System.out.println("TestInterceptor拦截器在整个请求结束之后被调用");
}
}
- 通过配置类配置拦截器:通过实现WebMvcConfigurer接口,实现addInterceptors方法
@Configuration
public class TestWebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TestInterceptor())
.addPathPatterns("/**");
}
}
3. AOP(面向切面编程)
AOP是一种编程范式,它允许你在不修改源代码的情况下,对程序的特定部分添加额外的功能。在Spring中,AOP是通过动态代理机制实现的。
不懂的可以看看这篇:掌握SpringBoot之AOP如此简单-CSDN博客
应用场景:
- 事务管理
- 日志记录
- 性能监控
- 安全控制
使用步骤:
日志记录:
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
//标题
String title() default "";
//业务类型
int businessType() default 0;
//操作类型
int operatorType() default 0;
}
@Aspect
@Component
public class LogAspect {
@Before("@annotation(controllerLog)")
public void boBefore(JoinPoint joinPoint, Log controllerLog) {
// 在方法执行之前进行调用
System.out.println("在controller方法执行之前进行调用: " + joinPoint.getSignature());
}
@AfterReturning(
pointcut = "@annotation(controllerLog)",
returning = "result"
)
public void doAfterReturning(JoinPoint joinPoint, Log controllerLog, Object result) {
// 在方法正常返回之后进行调用
System.out.println("在controller方法执行正常返回之后进行调用: " + result);
}
@AfterThrowing(
value = "@annotation(controllerLog)",
throwing = "e"
)
public void doAfterThrowing(JoinPoint joinPoint, Log controllerLog, Exception e) {
System.out.println("目标方法中抛出的异常: " + e);
}
}
测试:
@RestController
@RequestMapping("/test")
public class TestController {
@Log(title = "测试查询", operatorType = "query", businessType = "other")
@GetMapping("/test")
public String test() {
return "hello";
}
}
执行顺序:
简单理解:类似队列先进先出原则。
TestFilter过滤器------>初始化先执行(filter初始化)
应用程序启动完成
TestFilter过滤器------>进入web容器之前(filter)
TestInterceptor拦截器在请求处理之前进行调用
aop->在controller方法执行之前进行调用: String com.qzh.demo.filter.TestController.test()
aop->在controller方法执行正常返回之后进行调用: hello
TestInterceptor拦截器请求处理之后进行调用
TestInterceptor拦截器在整个请求结束之后被调用
TestFilter过滤器------>进入web容器之前 (filter)
TestFilter过滤器------>最后执行(filter销毁)
区别:
- 范围:过滤器可以应用于整个Web应用程序,拦截器只作用于Spring MVC处理的请求,而AOP可以应用于整个Spring应用上下文。
- 时机:过滤器在请求进入Servlet之前或响应离开Servlet之后调用,拦截器在请求到达Controller前后调用,AOP可以在方法的多个不同点(如方法执行前后、抛出异常时)调用。
- 实现方式:过滤器是基于Java规范实现的,拦截器是基于Spring的拦截器接口实现的,而AOP是基于Spring的代理机制实现的。
在选择使用过滤器、拦截器还是AOP时,需要根据具体的业务需求和处理范围来决定。例如,如果需要对所有请求进行日志记录,可以使用过滤器;如果需要在请求处理前后进行权限检查,可以使用拦截器;如果需要在方法执行前后进行日志记录或事务管理,可以使用AOP。