aop表达式排除功能的正确使用方法

/ 默认分类 / 0 条评论 / 861浏览

之前使用的项目中,因为需要使用到的数据源非常的多,所以使用的是mybatisplus的aop切换数据源的功能,并且我将数据源的配置写在了nacos配置中心,并且在切面中是按照service方法的方法名来动态的切换的但是这样有一个bug,就是每次在调用service的方法的时候就会切换一次数据源,所以像下面这样的情况:

public PageBean<List<Process>> getProcessByPagedatasource1(String param1) {

        String sid = httpClientApiService.getSid(param1).getSid();
        String status = processMapper.findSatusById(process.getId())
        
    }

这里首选controller进入的是getProcessByPagedatasource1方法,在这个方法中切换的数据源是datasource1,但是在这个service方法中还有一个调用service的方法httpClientApiService.getSid,这个service的时候就等于有切换一次数据源了,但是这次切换因为没有后缀,所以我的aop切面逻辑就是切换到了默认的数据源,所以这里数据源就被切换了,所以导致下面的processMapper获取数据的时候使用的就不是我们之前指定的那个datasource1这个数据源,所以这里我需要做一下aop的排除表达式;

这里也是有一个坑,使用排除表达式的时候,如果这样写,那么运行后等于没有起作用的,起作用的还是前面的表达式

@Pointcut("execution(* cn.whatsoft.service.*.*(..)) && !execution(* cn.whatsoft.service.HttpClientApiService.*(..))")
public void aspect(){}

或者是这样的

@Pointcut("execution(* cn.whatsoft.service.*.*(..)) and !execution(* cn.whatsoft.service.HttpClientApiService.*(..))")
public void aspect(){}

@Around("aspect()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {

按照上面的方式其实是错误的,程序是无法识别的,正确的使用方式是下面这样的写法


    @Pointcut("execution(* cn.whatsoft.service.*.*(..))")
    private void aspect() {

    }

    @Pointcut("execution(* cn.whatsoft.service.HttpClientApiService.*(..))")
    private void aspecthttpclient() {

    }

    @Pointcut("!aspecthttpclient() && aspect()")
    private void aspectall() {

    }



    @Around("aspect()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {


按照上面的方法,就可以在使用aop表达式的时候排除一些我们不需要作为切点的方法

ps:我使用的是springboot 2.2.3,在这个版本下我使用这样的功能的时候需要按照上面的方式才可以运行,不清楚是否与版本有关,大家参考一下