AspectJ连接指向仅建议“边界”执行和调用

时间:2015-09-12 11:50:21

标签: java aspectj pointcut

1)是否可以拦截(从外到内)一组类(或者可能是包,但不包括子包)和外部调用(从那些类到该组外部)的执行(或可能是调用) ()类,但不是“内部”执行/调用(从该组的任何类到同一组的任何类)只使用切入点定义(即不是建议中的额外Java代码)? 2)是否可以将该组指定为要在运行时加载的外部文件(加载时间编织)?

我想要的是编写一个工具来在运行时应用给定的方面,但开发人员可以在JVM启动时指定一组类(命令行或文本文件)。

我已经设法在建议中使用额外的Java反射代码实现了第1点,但它并不理想(慢),而且我不确定我是否可以从外部文件加载类/包名并让它们应用于AspectJ的:

private static final String PACKAGE_REGEX = "com.advisethispackage..*";
private static final String BEFORE_EXECUTION_AND_NEW_INVOCATION_FILTER = "((execution(* *(..))) || (execution(*.new(..)))) && within(" + PACKAGE_REGEX + ")";
private static final String CALL_INVOCATION_FILTER = "((call(* *(..))) || (call(*.new(..)))) && within(" + PACKAGE_REGEX + ")";

我尝试使用内部代码(显然我还没有真正理解),或者以这种方式排除调用...

private static final String CALL_INVOCATION_FILTER = "((call(* *(..))) || (call(*.new(..)))) && (!call(* " + WITHIN_REGEX + "(..))) && (!call(" + WITHIN_REGEX + ".new(..))) && within(" + WITHIN_REGEX + ")";

...但它未能排除一些同类调用。有什么想法吗?

我的aop.xml文件如下所示:

<aspectj>
  <aspects>
    <aspect name="org.my.aspects.RecordingAspect"/>
    <include within="org..*"/>
  </aspects>

  <weaver options="-verbose -debug -showWeaveInfo">
    <include within="com.advisethispackage..*"/>
    <include within="org.my.aspects..*"/>
  </weaver>
</aspectj>

我对AOP很新,只​​知道AspectJ,只使用注释,而不是AspectJ编译器或AJDT。 我正在使用aspectj-1.8.6和Java 8。

示例:我有4个班级(A,B,C,D)。 A在B上调用一个方法,调用C,调用D.B和C是我想建议的类(com.advisethispackage.B,com.advisethispackage.C),但A和D不是(com.dontadvisethispackage.A ,com.dontadvisethispackage.D)。我的RecordingAspect建议只打印出“类'X'上的调用方法”或“从类'X'调用方法'到类'Y'”。

录制时,我想输出为:

Invoked method on class 'B'
Invoking method from class 'C' to class 'D'

没有别的。 我也在录制“之后”的时刻,这会打印......

Returning from invocation of method on class 'D' called by class 'C'
Returning from invocation of method on class 'B'

...但我认为切入点定义应该是相同的。

由于

1 个答案:

答案 0 :(得分:0)

不知道你是否已经找到了这个,但是这里有两个切入点我用来匹配你的情况(使用AspectJ注释)

@Pointcut("call(* com.advisethispackage..*.*(..)) && !withincode(* com.advisethispackage..*.*(..))")
public void callFromOutsideToInside() {}

@Before("call(* (!com.advisethispackage..*).*(..)) && withincode(* com.advisethispackage..*.*(..))")
public void callFromInsideToOutside() {}

如果你想匹配构造函数:

@Pointcut("call(com.advisethispackage..*.new(..)) && !withincode(* com.advisethispackage..*.*(..))")
public void callFromOutsideToInside() {}

@Before("call((!com.advisethispackage..*).new(..)) && withincode(* com.advisethispackage..*.*(..))")
public void callFromInsideToOutside() {}