2016-11-22 260 views
0

我想创建一个本质上是动态的切入点表达式。 我有三个包 - 包1, 包2, 共同aspectj/spring中的动态切入点表达式aop

共同应始终inculded和基于系统属性我想在任何给定的时间来加载包1或包2

类似下面

private static final String PACKAGE = System.getProperty("packagePrefix"); 

@Around("execution(* "+PACKAGE+"..*.*(..)) && execution(* ..common.*(..))") 

我该如何做到这一点?

编辑:

我发现this这是很有趣的,我想能解决我的要求,但没有能够得到它的工作 所以这个环节说,有一个像下面

@Aspect 
public abstract class MyAspect { 

protected abstract pointcut(); 


@Before("pointcut()") 
public void myAdviceMethod() { 
// Advice code goes here 
} 
} 


public class ConcreteAspect extends MyAspect { 

@Pointcut("execution(* com.acme.*.*(..))") 
    protected pointcut() { 
) 
} 

下面包含在我的Java配置中

@Bean 
public ConcreteAspect myAspect() { 
    return new ConcreteAspect(); 
} 

但是,嗷嗷错误:

java.lang.IllegalArgumentException异常:在错误:: 0找不到引用 切入点切入点

我想在运行时,它不是能找出被覆盖的切入点方法,因此无法解决切入点。 任何想法如何解决这个问题?

回答

0

您可以使用内,这将扫描指定的包

@Pointcut( “内(..common ..(..)”) 公共无效CommonPackage(){}

@Pointcut( “内(..PACKAGE ..(..)”) 公共无效specificPackage(){}

而且使用@围绕/ @之前或任何建议为u需要您的具体情况 @Around (“执行(CommonPackage()& & SpecificPackage()“) 为不同的包编写切入点表达式并将它们绑定在一起。希望这可以帮助!

+0

感谢Sharmila的回应。但是这个PACKAGE将如何放置在你的第二个切入点中?记住PACKAGE是字符串,它在运行时从系统属性获得值 – SCoder

1

你可以使用if()子句,使支票是这样的:

aspect X { 
    before(): execution(* Code.*(..)) && 
    if(isOfInterest(thisJoinPointStaticPart.getSignature().getDeclaringType())) { 
    System.out.println("advice running"); 
    } 

    public static boolean isOfInterest(Class s) { 
    return s.getPackage().toString().startsWith(packagePrefix); 
    } 
} 

我想类似的东西将用于注释风格的语法工作。但是这种方法将包括每个匹配连接点的运行时测试。

+0

感谢Andy的response.But我猜if()只能用于如果我必须启用禁用通知。所以在我的情况下,我必须创建两个建议 - 一个用于package1,另一个用于package2。所以,如果我有50包,我必须创建50个建议。我真正想要的是在运行时在表达式中替换软件包名称。 – SCoder

+0

您可以用您认为合适的任何逻辑来替换“isOfInterest”方法的实现,但请记住,在您建议的每个连接点评估布尔方法的花费非常低。如果您的建议代码未被多次调用,或者性能不重要,则不应该成为问题。 –

+0

@NándorElődFekete - 我不能在isOfInterest中放任何逻辑,因为它只能返回boolean.From doc - if(...)主体可以是任何有效的Java布尔表达式,并且可以使用任何公开的形式,以及连接点形成thisJoinPoint,thisJoinPointStaticPart和thisJoinPointEnclosingStaticPart。 – SCoder