理解Spring AOP(权限校验为例)

AOP,全称Aspect Oriented Programming,意为面向切面编程,是一种编程范式,旨在通过预编译方式和运行期间动态代理实现程序功能的统一维护。以下是关于AOP的详细解释:

  1. 定义与原理
    • AOP是OOP(面向对象编程)的延续,是GoF设计模式的进一步发展,追求调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性。
    • 它允许开发人员将横切关注点(cross-cutting concerns)从应用程序的主要业务逻辑中分离出来,以便更好地实现代码重用和模块化。横切关注点指的是那些存在于应用程序多个模块中的功能,如日志记录、事务管理、安全性等。
    • AOP通过预编译方式和运行期动态代理技术,在不修改源代码的情况下给程序动态统一添加某种特定功能。
  2. 核心概念
    • 连接点(JoinPoint):程序执行过程中任意位置,如方法执行、异常抛出等。
    • 切入点(Pointcut):匹配连接点的式子,用于定义哪些连接点需要被增强。
    • 通知(Advice):在切入点处执行的操作,即共性功能,通常以方法的形式呈现。
    • 切面(Aspect):描述通知与切入点的对应关系,即定义何时何地执行哪些通知。
  3. 底层实现
    • AOP底层主要使用动态代理技术,包括JDK动态代理(基于接口)和CGLIB动态代理(基于父类)。
  4. 应用场景
    • 日志记录
    • 性能统计
    • 安全控制
    • 事务处理
    • 异常处理
    • 缓存优化
    • 权限控制 
  5. 在Spring框架中的应用
    • Spring框架为AOP提供了丰富的支持,允许通过分离应用的业务逻辑与系统级服务(如审计和事务管理)进行内聚性的开发。
    • 在Spring中,AOP通常通过AspectJ实现,开发人员可以使用注解或配置来定义切面,并将其与应用程序中的特定连接点关联起来。

成一个spring AOP的权限校验的代码

1.定义注解:首先,我们需要一个注解来标记需要进行权限校验的方法 

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)  
public @interface RequirePermission {  
    // 定义权限码,可以是一个字符串数组,用于支持多个权限  
    String[] value() default {};  
}

2.接下来,我们定义一个切面来拦截带有@RequirePermission注解的方法。

import org.aspectj.lang.JoinPoint;  
import org.aspectj.lang.ProceedingJoinPoint;  
import org.aspectj.lang.annotation.Around;  
import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.Pointcut;  
import org.aspectj.lang.reflect.MethodSignature;  
import org.springframework.stereotype.Component;  
  
@Aspect  
@Component  
public class PermissionAspect {  
  
    // 定义切入点,匹配所有带有@RequirePermission注解的方法  
    @Pointcut("@annotation(RequirePermission)")  
    public void checkPermissionPointcut() {}  
  
    // 环绕通知,在方法执行前后进行权限校验  
    @Around("checkPermissionPointcut()")  
    public Object checkPermission(ProceedingJoinPoint joinPoint) throws Throwable {  
        // 获取方法上的@RequirePermission注解  
        RequirePermission requirePermission = ((MethodSignature) joinPoint.getSignature()).getMethod().getAnnotation(RequirePermission.class);  
        if (requirePermission != null) {  
            // 获取权限码数组  
            String[] permissions = requirePermission.value();  
              
            // 这里应该有一个权限校验的逻辑,例如查询数据库或调用安全框架API  
            // 以下是一个简化的模拟检查  
            boolean hasPermission = checkUserPermissions(joinPoint, permissions);  
              
            if (!hasPermission) {  
                // 如果没有权限,抛出异常或进行其他处理  
                throw new RuntimeException("没有足够的权限执行此操作!");  
            }  
        }  
  
        // 如果有权限或没有@RequirePermission注解,则继续执行方法  
        return joinPoint.proceed();  
    }  
  
    // 这是一个模拟的权限校验方法,实际项目中应该根据业务需求实现  
    private boolean checkUserPermissions(JoinPoint joinPoint, String[] permissions) {  
        // 这里应该是获取当前用户权限并和需要的权限进行比对  
        // ...(此处省略具体实现)  
  
        // 模拟:始终返回true表示有权限(仅用于示例)  
        return true;  
    }  
}

3.最后,在需要进行权限校验的方法上添加@RequirePermission注解。

@Service  
public class SomeService {  
  
    @RequirePermission("READ_DATA") // 假设需要READ_DATA权限才能执行此方法  
    public String getData() {  
        // ... 方法实现  
        return "Data";  
    }  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值