springboot切面编程

SpringBoot切面编程

众所周知,spring最核心的两个功能是aop和ioc,即面向切面和控制反转。本文会讲一讲SpringBoot如何使用AOP实现面向切面的过程原理。

何为AOP

AOP(Aspect OrientedProgramming):面向切面编程,面向切面编程(也叫面向方面编程),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

利用AOP可以对我们边缘业务进行隔离,降低无关业务逻辑耦合性。提高程序的可重用性,同时提高了开发的效率。一般用于日志记录,性能统计,安全控制,权限管理,事务处理,异常处理,资源池管理。使用场景

AOP的一些核心概念

概念定义作用示例
横切关注点多个模块中共同涉及的功能,如日志、事务、权限等分离通用功能,避免代码冗余所有Service方法都需要记录执行时间
切面(Aspect)封装横切关注点的模块,包含切入点和通知将横切逻辑集中管理定义一个日志切面,统一处理日志记录
连接点(Join Point)程序执行中的特定点,如方法调用、字段修改等作为切面织入的候选位置某个Service方法被调用时
切入点(Pointcut)定义切面作用的具体位置,通过表达式匹配连接点精确控制切面影响的范围匹配所有以save开头的方法
通知(Advice)切面在连接点执行的操作,分为前置、后置、返回、异常、环绕通知实现具体的横切功能在方法执行前记录参数,执行后记录返回值
织入(Weaving)将切面与目标对象连接并创建代理对象的过程使切面逻辑在特定时机生效编译时织入(AspectJ)、运行时织入(Spring AOP)
目标对象(Target)被切面包裹的对象被增强的原始业务对象实际的UserService类
代理对象(Proxy)织入切面后生成的对象替代原始对象,执行时包含切面逻辑通过JDK动态代理生成的UserService代理对象

代码实现

这段代码展示了AOP(面向切面编程)在权限校验场景中的典型应用。通过自定义注解和环绕通知,实现了方法级别的权限拦截,避免了在每个业务方法中重复编写权限校验逻辑。

1. 自定义注解 @AuthCheck
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthCheck {
    String mustRole() default "";
}
  • 作用:标记需要进行权限校验的方法,并指定所需的角色(如@AuthCheck(mustRole = "ADMIN"))。
  • 元注解
    • @Target(ElementType.METHOD):注解仅可用于方法。
    • @Retention(RetentionPolicy.RUNTIME):注解在运行时保留,以便反射获取。
2. 切面类 AuthInterceptor
@Aspect
@Component
public class AuthInterceptor {
    @Resource
    private UserService userService;

    @Around("@annotation(authCheck)")
    public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
        // 1. 获取注解中指定的必须角色
        String mustRole = authCheck.mustRole();
        
        // 2. 获取当前登录用户
        HttpServletRequest request = ((ServletRequestAttributes) 
            RequestContextHolder.getRequestAttributes()).getRequest();
        User loginUser = userService.getLoginUser(request);
        
        // 3. 权限校验逻辑
        UserRoleEnum mustRoleEnum = UserRoleEnum.getEnumByValue(mustRole);
        if (mustRoleEnum == null) return joinPoint.proceed(); // 无需权限,放行
        
        UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValue(loginUser.getUserRole());
        if (userRoleEnum == null) throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        
        // 管理员权限校验
        if (mustRoleEnum == UserRoleEnum.ADMIN && userRoleEnum != UserRoleEnum.ADMIN) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
        }
        
        // 校验通过,执行原方法
        return joinPoint.proceed();
    }
}
  • 关键元素
    • @Aspect:声明该类为切面。
    • @Component:将切面注册为Spring Bean。
    • @Around("@annotation(authCheck)")
      • 环绕通知,拦截所有标记了@AuthCheck注解的方法。
      • authCheck参数绑定当前方法上的@AuthCheck注解实例。

AOP思想的体现

1. 关注点分离
  • 业务逻辑(如用户服务)与权限校验完全解耦。
  • 权限校验逻辑集中在切面中,无需在每个业务方法中重复编写。
2. 声明式编程
  • 通过@AuthCheck注解在方法上声明所需权限,简洁直观。
  • 示例:
    @AuthCheck(mustRole = "ADMIN")
    public void deleteUser(Long userId) {
        // 业务逻辑(无需关心权限校验)
    }
    
3. 动态代理机制
  • Spring AOP通过动态代理(JDK或CGLIB)在运行时生成代理对象。
  • 代理对象在调用目标方法前后插入权限校验逻辑:
    调用代理方法 → 执行前置校验 → 执行目标方法 → 执行后置逻辑
    

执行流程

  1. 方法调用:客户端调用标记了@AuthCheck的方法。
  2. 代理拦截:Spring AOP拦截调用,执行AuthInterceptor的环绕通知。
  3. 权限校验
    • 从注解获取所需角色(如ADMIN)。
    • 从当前请求获取登录用户信息。
    • 比较用户角色与注解要求的角色。
  4. 结果处理
    • 校验通过:执行原方法。
    • 校验失败:抛出BusinessException
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

耄耄爱哈气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值