AOP之观察

    前段时间写了一个AOP的小例子,因为要在一些公共的方法前面加一个分布式的redis锁,故采用了AOP. 就是写了一个切面,切面的信息如下:
@Pointcut(value = "execution(* com.gz.eim.ac.trans.service.finance.impl.*.deal*(..))")
    public void point(){

    }

    @Around(value = "point()")
    public void around(ProceedingJoinPoint joinPoint){
        String clazzName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        String lockName = clazzName + "." +methodName;
        logger.info("FinanceTransServiceAspect.around start, 执行类:{}.{} 方法 start, 此服务加锁的名称为:{}", clazzName, methodName, lockName);
        RLock rLock = tryLock(lockName);
        try {
            joinPoint.proceed();
        } catch (Throwable e) {
            logger.error("FinanceTransServiceAspect.around error, 执行类:{}.{} 方法 start, 此服务加锁的名称为:{}, error: ", clazzName, methodName, lockName, e);
        } finally {
            if (rLock.isLocked()) {
                rLock.unlock();
            }
        }
        logger.info("FinanceTransServiceAspect.around end, 执行类:{}.{} 方法 end, 此服务加锁的名称为:{}", clazzName, methodName, lockName);
    }
 这里用到了一个切面表达式
execution(* com.gz.eim.ac.trans.service.finance.impl.*.deal*(..))

本来这里没有问题,但是我在一个deal开头的方法中设置了返回值,返回一个boolean类型,
也就是service层的这个deal开头的方法返回了一个boolean类型,但是controller层接收这个boolean类型的时候报错了:
org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public boolean com.gz.eim.ac.trans.service.finance.impl.InsuranceValueCurrentReturnReceivableServiceImpl.dealInsuranceValueCurrentReturnReceivableCurrent(java.util.Date,java.util.Date,java.util.Date,java.util.Date,java.lang.String,boolean)

上面的意思是说返回值无法转换成null,殊不知基本数据类型boolean 是不能接收null,这也是基本数据类型与包装数据类型一个很大的区别。
报错如上,查找发现 是因为 我的切面中环绕通知没有返回值,所以把真正service层的返回值吃掉了,验证得知,controller层拿不到这个返回值。
解决方案:
第一:将service层的这个boolen 基本数据类型改为 包装数据类型 Boolean
改为包装数据类型之后发现没有上面那个报错了,但是Controller层依然接受不到返回值
原因还是得看切面中的环绕通知没有处理返回值
第二:对切面中的环绕通知对返回值进行处理。

@Around(value = "point()")
    public Object around(ProceedingJoinPoint joinPoint){
        String clazzName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        String lockName = clazzName + "." +methodName;
        logger.info("FinanceTransServiceAspect.around start, 执行类:{}.{} 方法 start, 此服务加锁的名称为:{}", clazzName, methodName, lockName);
        RLock rLock = tryLock(lockName);
        try {
            return joinPoint.proceed();
        } catch (Throwable e) {
            logger.error("FinanceTransServiceAspect.around error, 执行类:{}.{} 方法 start, 此服务加锁的名称为:{}, error: ", clazzName, methodName, lockName, e);
        } finally {
            if (rLock.isLocked()) {
                rLock.unlock();
            }
        }
        logger.info("FinanceTransServiceAspect.around end, 执行类:{}.{} 方法 end, 此服务加锁的名称为:{}", clazzName, methodName, lockName);
        return null;
    }

如上所示,没有再报错了,并且Controller层也能正常接收到了返回值。

那来看一下对于本身就没有返回值的deal开头的方法有没有影响,发现没有影响搞定!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值