aspectj - AND 和 OR 在同一个切入点

aspectj - AND and OR in the same pointcut

getAll(...)getRec(...) 方法在 com.acme.dao.impl.*DaoImpl 类 中被调用但不包括 com.acme.dao.impl.*ViewDaoImpl 类.

我可以用

完成第一个要求
execution(* com.acme.dao.impl.*DaoImpl.getAll(..)) || execution(* com.acme.dao.impl.*DaoImpl.getNRecs(..))

但不确定如何排除 *ViewDaoImpl 类。
我想我应该做类似

的事情
!execution(* com.acme.dao.impl.*ViewDaoImpl.*(..))

但是如何添加到包含表达式?

谢谢,
五、

您有多种选择。与您已有的最接近的是:

(execution(* com.acme.dao.impl.*DaoImpl.getAll(..)) || execution(* com.acme.dao.impl.*DaoImpl.getNRecs(..))) &&
!execution(* com.acme.dao.impl.*ViewDaoImpl.*(..))

不过你也可以用这个,我觉得可读性更好一点:

within(com.acme.dao.impl.*DaoImpl) && !within(*..*ViewDaoImpl) &&
(execution(* getAll(..)) || execution(* getNRecs(..)))

假设所有 DAO 类 将实现与上面给出的相同的接口,这也可以工作(Dao+ 捕获所有实现 类 及其子 类) :

within(com.acme.dao.impl.Dao+) && !within(*..*ViewDaoImpl) &&
(execution(* getAll(..)) || execution(* getNRecs(..)))

这是一个纯 AspectJ 示例,但它应该与 Spring AOP 的方面代码相同:

示例应用程序 类:

package com.acme.dao.impl;

import java.util.List;

public interface Dao {
  List getAll();
  List getNRecs();
  void doSomething();
}
package com.acme.dao.impl;

import java.util.ArrayList;
import java.util.List;

public class FirstDaoImpl implements Dao {
  @Override
  public List getAll() {
    return new ArrayList();
  }

  @Override
  public List getNRecs() {
    return new ArrayList();
  }

  @Override
  public void doSomething() {}
}
package com.acme.dao.impl;

import java.util.ArrayList;
import java.util.List;

public class SecondDaoImpl implements Dao {
  @Override
  public List getAll() {
    return new ArrayList();
  }

  @Override
  public List getNRecs() {
    return new ArrayList();
  }

  @Override
  public void doSomething() {}
}
package com.acme.dao.impl;

import java.util.ArrayList;
import java.util.List;

public class MyViewDaoImpl implements Dao {
  @Override
  public List getAll() {
    return new ArrayList();
  }

  @Override
  public List getNRecs() {
    return new ArrayList();
  }

  @Override
  public void doSomething() {}
}

驱动申请:

package de.scrum_master.app;

import java.util.Arrays;

import com.acme.dao.impl.Dao;
import com.acme.dao.impl.FirstDaoImpl;
import com.acme.dao.impl.MyViewDaoImpl;
import com.acme.dao.impl.SecondDaoImpl;

public class Application {
  public static void main(String[] args) throws InstantiationException, IllegalAccessException {
    for (Class<?> clazz : Arrays.asList(FirstDaoImpl.class, SecondDaoImpl.class, MyViewDaoImpl.class)) {
      Dao dao = (Dao) clazz.newInstance();
      dao.getAll();
      dao.getNRecs();
      dao.doSomething();
    }
  }
}

看点:

我在切入点字符串中添加了很多换行符和缩进,当然你不需要这样做。在 Whosebug 上的这个 Q/A 场景中,这里只是为了清楚起见。

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class DaoAspect {
  @Before(
    "(" + 
      "execution(* com.acme.dao.impl.*DaoImpl.getAll(..)) || " + 
      "execution(* com.acme.dao.impl.*DaoImpl.getNRecs(..))" + 
    ") && " + 
    "!execution(* com.acme.dao.impl.*ViewDaoImpl.*(..))"
  )
  public void firstVariant(JoinPoint thisJoinPoint) {
    System.out.println("[1] " + thisJoinPoint);
  }

  @Before(
    "within(com.acme.dao.impl.*DaoImpl) && " +
    "!within(*..*ViewDaoImpl) && " +
    "(" +
      "execution(* getAll(..)) || " +
      "execution(* getNRecs(..))" +
    ")" 
  )
  public void secondVariant(JoinPoint thisJoinPoint) {
    System.out.println("[2] " + thisJoinPoint);
  }

  @Before(
    "within(com.acme.dao.impl.Dao+) && " +
    "!within(*..*ViewDaoImpl) && " +
    "(" +
      "execution(* getAll(..)) || " +
      "execution(* getNRecs(..))" +
    ")" 
  )
  public void thirdVariant(JoinPoint thisJoinPoint) {
    System.out.println("[3] " + thisJoinPoint);
  }
}

控制台日志:

[1] execution(List com.acme.dao.impl.FirstDaoImpl.getAll())
[2] execution(List com.acme.dao.impl.FirstDaoImpl.getAll())
[3] execution(List com.acme.dao.impl.FirstDaoImpl.getAll())
[1] execution(List com.acme.dao.impl.FirstDaoImpl.getNRecs())
[2] execution(List com.acme.dao.impl.FirstDaoImpl.getNRecs())
[3] execution(List com.acme.dao.impl.FirstDaoImpl.getNRecs())
[1] execution(List com.acme.dao.impl.SecondDaoImpl.getAll())
[2] execution(List com.acme.dao.impl.SecondDaoImpl.getAll())
[3] execution(List com.acme.dao.impl.SecondDaoImpl.getAll())
[1] execution(List com.acme.dao.impl.SecondDaoImpl.getNRecs())
[2] execution(List com.acme.dao.impl.SecondDaoImpl.getNRecs())
[3] execution(List com.acme.dao.impl.SecondDaoImpl.getNRecs())

如您所见,所有三个变体的作用完全相同。根据自己的喜好选择。