过滤器==>拦截器==>aop
过滤器
过滤器(Filter)是在Java Web应用程序中用于对HTTP请求和响应进行预处理和修改的组件。它可以在请求到达Servlet之前或之后拦截请求,并对请求进行过滤或修改
- 访问控制:通过检查用户的权限或身份验证信息,过滤器可以拦截请求并决定是否允许用户访问受限资源。
- 请求修改:过滤器可以修改请求的参数、头部信息或内容,以满足特定的需求。例如,可以对请求数据进行编码、解码或加密。
- 响应修改:过滤器可以修改服务器返回的响应数据,例如添加额外的头部信息、压缩响应内容等。
- 日志记录:过滤器可以用于记录请求和响应的日志信息,以便进行监控、故障排查和性能分析
@WebFilter("/*") // 这里定义了过滤器拦截的URL模式,这个例子表示拦截所有请求
public class LoggingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 在过滤器初始化时执行的操作,可以用来进行一些初始化工作
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 在请求被处理之前执行的操作
System.out.println("Logging request: " + request.getRemoteAddr() + " " + ((HttpServletRequest) request).getRequestURI());
// 让请求继续传递给下一个过滤器,直到请求被发送到目标资源
chain.doFilter(request, response);
// 在请求被处理之后执行的操作
System.out.println("Logging response: " + response.getContentType());
}
@Override
public void destroy() {
// 在过滤器被销毁时执行的操作,可以用来进行一些清理工作
}
}
拦截器
拦截器(Interceptor)是在Web应用程序中常见的一种组件,用于在请求到达控制器(Controller)之前或之后进行拦截和处理
- 身份验证和权限控制:拦截器可以用于检查用户的身份验证信息,并根据权限决定是否允许用户访问受限资源。
- 日志记录:拦截器可以记录请求和响应的详细日志信息,用于监控和故障排查。
- 性能监控:拦截器可以用于测量请求的处理时间,并收集性能指标,以便进行性能分析和优化。
- 异常处理:拦截器可以捕获控制器处理过程中发生的异常,并根据需要进行处理或转发到错误页面
@Configuration
public class BmsMvcConfig implements WebMvcConfigurer {
@Autowired
private AuthorityInterceptor authorityInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authorityInterceptor)
.excludePathPatterns("/login.html")
.addPathPatterns("/api/**");
}
}
AOP
AOP(Aspect-Oriented Programming,面向切面编程)是一种编程范式,用于通过横切关注点(cross-cutting concerns)来分离关注点,实现对程序行为的模块化和重用。
在AOP中,关注点是指影响应用程序的很多部分的功能性需求。例如日志记录、安全性、事务管理等都是常见的关注点。这些关注点通常会散布在应用程序的多个模块中,与应用程序的核心业务逻辑相互交织在一起。
AOP通过定义切面(Aspect)来解决这种散布在多个模块中的关注点问题。切面是一个模块化单元,它封装了特定关注点的行为,并可以跨越应用程序的多个模块进行重用。
AOP框架提供了一种方式来定义切面,并将其与应用程序的特定连接点(join points)相关联。连接点是在应用程序执行过程中可以插入切面代码的点,例如方法调用、异常处理、对象创建等。
AOP框架通常提供以下功能:
- 切面(Aspect):定义关注点和切面行为。
- 连接点(Join Point):定义切面可以插入的程序执行点。
- 通知(Advice):切面的具体行为,包括前置通知、后置通知、环绕通知,异常通知,最终通知
- 前置通知(Before advice): 在目标方法执行之前执行的通知。前置通知可以用于执行一些准备操作,例如权限检查、日志记录等。
- 后置通知(After returning advice): 在目标方法成功执行之后(没有抛出异常)执行的通知。后置通知可以用于执行一些清理操作或记录方法的返回值。
- 环绕通知(Around advice): 在目标方法执行之前和之后都可以执行的通知。环绕通知可以完全控制目标方法的执行,包括决定是否执行目标方法以及如何处理返回值。
- 异常通知(After throwing advice): 在目标方法抛出异常之后执行的通知。异常通知可以用于处理目标方法抛出的异常情况。
- 最终通知(After (finally) advice): 在目标方法执行之后(无论是否抛出异常)都会执行的通知。最终通知通常用于执行一些清理操作,例如释放资源等。
- 切点(Pointcut):定义一组连接点的集合,用于确定切面的具体应用位置。
- 引入(Introduction):允许向现有的类添加新方法或属性。
@Aspect
@Component
public class LoggingAspect {
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {
// 定义一个切点,匹配com.example.service包下的所有方法
}
@Before("serviceMethods()")
public void beforeMethod(JoinPoint joinPoint) {
// 在目标方法执行之前执行的操作
System.out.println("Logging before method: " + joinPoint.getSignature().toLongString());
}
@Around("serviceMethods()")
public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
// 在目标方法执行前后执行的操作
System.out.println("Logging around method (before): " + joinPoint.getSignature().toLongString());
Object result = joinPoint.proceed(); // 执行目标方法
System.out.println("Logging around method (after): " + joinPoint.getSignature().toLongString());
return result;
}
@AfterReturning(pointcut = "serviceMethods()", returning = "result")
public void afterReturningMethod(JoinPoint joinPoint, Object result) {
// 在目标方法返回结果后执行的操作
System.out.println("Logging after returning method: " + joinPoint.getSignature().toLongString());
}
@AfterThrowing(pointcut = "serviceMethods()", throwing = "exception")
public void afterThrowingMethod(JoinPoint joinPoint, Throwable exception) {
// 在目标方法抛出异常后执行的操作
System.out.println("Logging after throwing method: " + joinPoint.getSignature().toLongString());
}
}