通过自定义注解+AOP切面的方式,可以实现日志记录、权限控制、性能监控、事务管理、缓存管理、异常处理等功能,以下以权限控制为例,介绍一下自定义注解+AOP处理方式的使用。
步骤1:定义注解
用于标记需要权限校验的方法
package com.example.security.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) // 该注解应用于方法
@Retention(RetentionPolicy.RUNTIME) // 运行时保留,以便AOP切面可以访问
public @interface RequirePermission {
String value(); // 定义一个属性,用于指定需要的权限
}
步骤2:编写切面
用于实现权限校验逻辑。
package com.example.security.aspect;
import com.example.security.annotation.RequirePermission;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class PermissionCheckAspect {
@Autowired
private UserService userService; // 假设UserService用于获取用户信息和权限
@Around("@annotation(permissionAnnotation)")
public Object checkPermission(ProceedingJoinPoint joinPoint, RequirePermission permissionAnnotation) throws Throwable {
// 获取当前认证信息
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
throw new UnauthorizedException("用户未认证");
}
// 获取用户权限,这里简化处理,实际情况可能更复杂
String requiredPermission = permissionAnnotation.value();
if (!userService.hasPermission(authentication.getName(), requiredPermission)) {
throw new UnauthorizedException("没有足够的权限访问:" + requiredPermission);
}
// 权限校验通过,执行原方法
return joinPoint.proceed();
}
}
步骤3:使用注解
在需要权限控制的服务方法上使用
@RequirePermission
注解,并指定所需的权限。
package com.example.service;
import com.example.security.annotation.RequirePermission;
import org.springframework.stereotype.Service;
@Service
public class SomeService {
@RequirePermission("ADMIN_ACCESS")
public void performAdminAction() {
// 需要管理员权限的方法逻辑
}