SpringBoot AOP拦截

本文介绍如何使用 Spring AOP 进行方法级别的权限控制和读写分离操作。通过 @Aspect 注解定义切面,并利用 @Before 和 @Around 等注解实现对 Controller 方法的拦截与权限验证。此外,还展示了如何对带有特定注解的方法进行拦截以及对 DAO 层方法进行读写分离。

拦截指定的Controller里面的方法

可以在指定拦截的Controller中方法执行之前,进行请求拦截,比如对一些需要授权验证的方法进行拦截判断cookie及权限。

@Aspect @Component

    @Pointcut("execution(public * com.xxx.controller.*.*(..))" +
            "&& !execution(public * com.xxx.controller.WelcomeController.*(..))")
    public void verify() {
    }

    @Before("verify()")
    public void doVerify(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 用户身份认证
        UserVO user = UserAuth.getUserInfoFromToken(request, redisClient, authService);
        // 同步用户信息到 threadlocal
        ThreadLocalUtil.set(CommonConstant.USERID, user.getId());
        ThreadLocalUtil.set(CommonConstant.USERNAME, user.getName());

        // 用户鉴权
        RequestPermissions permissions = UserPermission.getAnnotation(joinPoint);
        if (null != permissions) {
            UserPermission.checkUserPermissionAllow(request, authService, user, permissions);
        }
    }

拦截所有打上指定注解的方法

比如在程序中控制读写分离,可以定义一个@Slave注解,在执行指定service的方法之前判断是否存在@Slave注解。

 @Before("@annotation(test)")// 拦截被TestAnnotation注解的方法;如果你需要拦截指定package指定规则名称的方法,可以使用表达式execution(...),具体百度一下资料一大堆
 public void beforeTest(JoinPoint point, TestAnnotation test) throws Throwable {
  System.out.println("beforeTest:" + test.name());
 }
 
 @After("@annotation(test)")
 public void afterTest(JoinPoint point, TestAnnotation test) {
  System.out.println("afterTest:" + test.name());
 }

    @Around("@annotation(slave)")
    public Object proceed(ProceedingJoinPoint proceedingJoinPoint, Slave slave) throws Throwable {
        try {
            logger.info("set database connection to slave");
            DatabaseContextHolder.setDatabaseType(DatabaseType.SLAVE);
            return proceedingJoinPoint.proceed();
        } finally {
            DatabaseContextHolder.clearDbType();
            logger.info("restore database connection");
        }
    }

拦截dao数据库操作方法,做读写分离

@Aspect
@Component
public class DataSourceAspect {
 
    @Before("execution(* com.xxx.firstboot.dao.*.*(..))")
    public void setDataSourceKey(JoinPoint point){
         //连接点所属的类实例是ShopDao
         if(point.getTarget() instanceof ShopDao){
             DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb2);
         }else{//连接点所属的类实例是UserDao(当然,这一步也可以不写,因为defaultTargertDataSource就是该类所用的mytestdb)
             DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb);
         }
     }

}

转载于:https://my.oschina.net/u/1000241/blog/1591570

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值