下面是我准备的详解Spring面向切面AOP拦截器的攻略。
什么是AOP
AOP(Aspect Oriented Programming)是一种编程思想,通过在不影响主业务逻辑的情况下,往程序中添加一些辅助功能和处理逻辑。AOP思想的核心是“切面”(Aspect),切面可以看作是一个包含了若干通用处理逻辑的类,这些通用处理逻辑可以在不同的拦截点上进行重复利用,提高代码的重用性和可维护性。
Spring中的AOP
Spring框架支持基于注解或XML配置的AOP实现,常见的拦截器包括前置通知、后置通知、异常通知、最终通知和环绕通知等。
在Spring中实现AOP拦截器需要满足以下两个条件:
- 必须采用面向接口编程的方式,即被拦截的类必须实现一个接口,否则程序将编译报错;
- 必须配置Spring AOP的执行器(Advisor),告诉Spring在哪些拦截点上调用执行器执行通知。
下面演示两个基于注解方式实现AOP的示例。
实现1:日志记录拦截器
创建一个名为“LogInterceptor”的类,使用Spring AOP注解,实现前置通知,在被拦截方法执行之前打印日志。
@Component
@Aspect
public class LogInterceptor {
@Before("execution(* com.example.demo.service..*.*(..))")
public void before(JoinPoint joinPoint) {
System.out.println("方法执行前:" + joinPoint.getSignature());
}
}
这里使用了@Aspect
注解将LogInterceptor
类标记为一个切面,@Before
注解表示前置通知,它的参数指定了拦截的方法执行的切点表达式,这里使用了execution表达式来告诉Spring对某个包(com.example.demo.service)下的所有类的所有方法做拦截。
实现2:权限控制拦截器
创建一个名为“SecurityInterceptor”的类,使用Spring AOP注解,实现环绕通知,在被拦截的方法执行之前检查用户是否有权限,如果有权限则继续执行,否则抛出异常。
@Component
@Aspect
public class SecurityInterceptor {
@Autowired
private PermissionService permissionService;
@Around("execution(* com.example.demo.controller..*(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String token = request.getHeader("Authorization");
if (StringUtils.isEmpty(token)) {
throw new UnauthorizedException("用户未登录");
}
int userId = JwtUtil.parseToken(token);
if (permissionService.checkPermission(userId, joinPoint.getSignature().getName())) {
return joinPoint.proceed();
} else {
throw new ForbiddenException("权限不足");
}
}
}
这里使用了@Around
注解来标记环绕通知,它的参数同样是一个execution表达式,表示对某个包(com.example.demo.controller)下的所有方法做拦截。在环绕通知中,我们可以通过ProceedingJoinPoint
对象来获取被拦截的方法名称、参数等信息,并通过RequestContextHolder
来获取HTTP请求对象,进而获取请求头中的用户身份信息。如果用户身份信息不存在,则抛出“用户未登录”的异常;如果用户有权限,则继续执行被拦截的方法,否则抛出“权限不足”的异常。
总结
在Spring中实现AOP拦截器可以帮助我们解决一些横切关注点的问题,提高代码的可维护性和代码的重用性。通过本文,我们了解到Spring的AOP实现需要面向接口编程,必须配置执行器。我们还演示了两个基于注解的AOP拦截器,分别是日志记录拦截器和权限控制拦截器。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解spring面向切面aop拦截器 - Python技术站