AOP技术的事务管理和访问权限控制

事务管理:

// 自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomTransactional {
String value() default "";
boolean readOnly() default false;
}

// 业务类
@Service
public class UserService {

@CustomTransactional(value = "userTx", readOnly = false)
public User createUser(User user) {
// 业务逻辑
return userRepository.save(user);
}

@CustomTransactional(value = "queryTx", readOnly = true)
public User getUser(Long id) {
return userRepository.findById(id).orElse(null);
}
}

// AOP切面
@Aspect
@Component
public class TransactionAspect {

@Around("@annotation(tx)")
public Object handleTransaction(ProceedingJoinPoint joinPoint,
CustomTransactional tx) throws Throwable {

System.out.println("=== 事务开始 ===");
System.out.println("事务名称:" + tx.value());
System.out.println("是否只读:" + tx.readOnly());
System.out.println("目标方法:" + joinPoint.getSignature().getName());

// 获取方法参数
Object[] args = joinPoint.getArgs();

// 遍历参数,找到 User 对象并修改
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof User) {
User user = (User) args[i];
user.setName("修改后的姓名");
// 注意:如果需要对修改后的参数进行后续处理,可以重新设置
args[i] = user;
System.out.println("已修改 User 的 name 为:" + user.getName());
break;
}
}


try {
Object result = joinPoint.proceed();
System.out.println("=== 事务提交 ===");
return result;
} catch (Exception e) {
System.out.println("=== 事务回滚 ===");
throw e;
}
}
}

 

权限管理:

注解:

// 权限注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequiresPermission {
String value(); // 权限标识
String description() default "";
}

// 角色注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequiresRole {
String value(); // 角色标识
Logical logical() default Logical.AND;

enum Logical {
AND, OR
}
}

// 数据权限注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataPermission {
String type(); // 数据权限类型
String field() default "createdBy"; // 过滤字段
}

 

权限切面:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;

@Aspect
@Component
public class PermissionAspect {

@Autowired(required = false)
private HttpServletRequest request;

@Autowired
private PermissionService permissionService;

/**
* 权限校验
*/
@Before("@annotation(requiresPermission)")
public void checkPermission(JoinPoint joinPoint,
RequiresPermission requiresPermission) {
String permission = requiresPermission.value();
String currentUser = getCurrentUser();

if (!permissionService.hasPermission(currentUser, permission)) {
throw new AccessDeniedException(
"用户 " + currentUser + " 没有权限: " + permission
);
}
}

/**
* 角色校验
*/
@Before("@annotation(requiresRole)")
public void checkRole(JoinPoint joinPoint, RequiresRole requiresRole) {
String[] requiredRoles = requiresRole.value().split(",");
String currentUser = getCurrentUser();

if (requiresRole.logical() == RequiresRole.Logical.AND) {
// 需要同时拥有所有角色
for (String role : requiredRoles) {
if (!permissionService.hasRole(currentUser, role.trim())) {
throw new AccessDeniedException(
"用户 " + currentUser + " 缺少角色: " + role
);
}
}
} else {
// 拥有任意一个角色即可
boolean hasAnyRole = Arrays.stream(requiredRoles)
.anyMatch(role -> permissionService.hasRole(currentUser, role.trim()));

if (!hasAnyRole) {
throw new AccessDeniedException(
"用户 " + currentUser + " 缺少所需角色"
);
}
}
}

/**
* 数据权限处理
*/
@Before("@annotation(dataPermission)")
public void applyDataPermission(JoinPoint joinPoint,
DataPermission dataPermission) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Object[] args = joinPoint.getArgs();

// 获取当前用户信息
String currentUser = getCurrentUser();

// 根据数据权限类型处理参数
switch (dataPermission.type()) {
case "SELF":
// 只能操作自己的数据
applySelfDataPermission(args, dataPermission.field(), currentUser);
break;
case "DEPT":
// 只能操作本部门数据
applyDeptDataPermission(args, currentUser);
break;
case "ALL":
// 可以操作所有数据,不需要过滤
break;
default:
throw new IllegalArgumentException("未知的数据权限类型: " + dataPermission.type());
}
}

/**
* 前置权限校验(在方法执行前)
*/
@Before("execution(* com.example.service.*.*(..)) && " +
"(@annotation(org.springframework.web.bind.annotation.GetMapping) || " +
"@annotation(org.springframework.web.bind.annotation.PostMapping) || " +
"@annotation(org.springframework.web.bind.annotation.PutMapping) || " +
"@annotation(org.springframework.web.bind.annotation.DeleteMapping))")
public void preCheckPermission(JoinPoint joinPoint) {
// 检查方法是否需要登录
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();

// 如果方法上有@RequiresLogin注解,检查是否登录
if (method.isAnnotationPresent(RequiresLogin.class)) {
if (getCurrentUser() == null) {
throw new AuthenticationException("用户未登录");
}
}
}

/**
* 后置权限校验(在方法执行后)
*/
@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))",
returning = "result")
public void postCheckPermission(JoinPoint joinPoint, Object result) {
// 对返回结果进行权限过滤
if (result instanceof List) {
List<?> list = (List<?>) result;
// 过滤掉用户无权查看的数据
filterResultByPermission(list);
}
}

private void applySelfDataPermission(Object[] args, String field, String currentUser) {
// 实现自己的数据权限逻辑
// 例如:在查询条件中添加 createdBy = currentUser
}

private void applyDeptDataPermission(Object[] args, String currentUser) {
// 实现部门数据权限逻辑
// 例如:在查询条件中添加 deptId = currentUserDeptId
}

private String getCurrentUser() {
// 从SecurityContext或Session中获取当前用户
// 这里简化处理
return request != null ? request.getHeader("X-User-Id") : "anonymous";
}
}

service层权限切面应用:

import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class BusinessService {

@RequiresPermission("user:create")
@RequiresRole("ADMIN,MANAGER")
public User createUser(User user) {
// 只有拥有user:create权限且是ADMIN或MANAGER角色的用户才能执行
return userRepository.save(user);
}

@RequiresPermission("user:view")
@DataPermission(type = "DEPT")
public List<User> getUsersByDept(Long deptId) {
// 拥有user:view权限的用户只能查看本部门的用户
return userRepository.findByDeptId(deptId);
}

@RequiresPermission("user:edit")
@DataPermission(type = "SELF", field = "updatedBy")
public User updateUser(User user) {
// 只能修改自己更新的数据
return userRepository.save(user);
}

@RequiresPermission("report:export")
@RequiresRole(value = "ADMIN,FINANCE", logical = RequiresRole.Logical.OR)
public ReportData exportReport() {
// 拥有report:export权限且是ADMIN或FINANCE角色的用户可以导出报表
return reportService.generateReport();
}
}

 

posted @ 2026-01-01 05:57  人在代码在  阅读(3)  评论(0)    收藏  举报