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())
如您所见,所有三个变体的作用完全相同。根据自己的喜好选择。
当 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())
如您所见,所有三个变体的作用完全相同。根据自己的喜好选择。