如何使用springAop实现拦截目标方法,并且给目标方法传值,实现权限等功能。

如何使用springAop实现拦截目标方法,并且给目标方法传值,实现权限等功能

今天需要加一个需求。
大致意思是用户可以切换为其他用户的角色,用其他用户的角色权限进行各种操作。
在项目本身是有个缓存去保存用户的登录信息的。
简单一点的做法,在所有涉及到角色权限的方法上,都加一个方法进行判断用户是否使用的其他角色权限。
不过由于涉及的方法实在太多,如果这么做的话势必会增加很多工作量导致代码臃肿重复。
那么我想应该是可以通过Spring AOP面向切面实现的。
在不修改原代码的情况给目标方法增加新的功能。

在项目中新建一个类ApplyOrderAspect
具体实现方法如下

@Slf4j
@Component
@Aspect
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ApplyOrderAspect {

    private final UserAuthorizeMapper userAuthorizeMapper;
    private final ApplyOrderDao orderDao;
    private final UserMapper userMapper;


    @Pointcut("@annotation(com.XXX.GetUserInfo)")
    public void getUserInfo(){}


    @Around("getUserInfo()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("进入切面。。。before");
        Object[] args = joinPoint.getArgs();
        // 识别当前登录者的身份
        User user = orderDao.getUser();
        // 判断是否切换了其他角色的权限
        UserAuthorize userAuthorize = userAuthorizeMapper.selectOne(new LambdaQueryWrapper<UserAuthorize>()
                .eq(UserAuthorize::getAuthorizeUserId, user.getId())
                .eq(UserAuthorize::getOperation, ConstantCode.ONE));
        if(ObjectUtils.isNotEmpty(userAuthorize)){
            LocalDateTime nowTime= LocalDateTime.now();
            if(nowTime.isAfter(userAuthorize.getStartTime()) && nowTime.isBefore(userAuthorize.getEndTime())){
                User otherUser = userMapper.selectById(userAuthorize.getUserId());
                args[0]  = otherUser;
            }else {
                throw new BizException(1008,"You are not authorized to operate as "+userAuthorize.getUserName());
            }
        }else {
            args[0] = user;
        }
        return joinPoint.proceed(args);
    }

}		

以上为具体代码实现
ProceedingJoinPoint这个类比较关键,它继承了JointPoint。
可以通过反射的方式获取到目标方法的入参。
Object[] args = joinPoint.getArgs();
获取到的参数为数组形式。

定义切入点方法getUserInfo(),使用@Pointcut注解指定一个注解类
在这里插入图片描述

在拦截方法上around()上加上注解@Around(“getUserInfo()”),这个是表明使用注解拦截目标方法。在所需要拦截的方法上加上 @GetUserInfo注解

接下来再看看业务代码service和impl中是怎么接受值的
在这里插入图片描述
我是直接在传参中 new User(),需要放在方法参数第一个,因为在拦截器中被赋值到了数组第一个args[0] = user,

然后再具体的impl实现类中
在这里插入图片描述
方法体上加上注解 @GetUserInfo,表明这个方法被拦截,User中也能被注入相应的值

虽然拦截目标方法很多忠,比如拦截具体方法,拦截某个类中所有方法等,但对于后期突然增加的需求,使用注解的方式比较方便。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值