Aspectj:在@Aspect中获取@Pointcut详细信息

时间:2011-03-12 00:23:23

标签: aspectj

我有一个方面被调用任何定义的切入点,类似于这样:

@Around("pointcut1(request) || pointcut2(request) || pointcut3(request)")
public ModelAndView myAspect(ProceedingJoinPoint proceedingJp, 
                             HttpServletRequest request)
{
    //do something.
}

所以在这个方面,我需要知道这个myAspect被调用到哪个切入点(pointcut1 / 2/3)。我有什么理由可以解决这个问题吗?

添加更多细节......

我在@Aspect(方法)中没有任何参数。我知道我可以获得JoinPoint,但它对我来说效果不佳。 像这样的东西会很方便....

@Around("pointcut1(request) || pointcut2(request) || pointcut3(request)")
public ModelAndView myAspect(ProceedingJoinPoint proceedingJp, PointCut pc ,HttpServletRequest request){
if (pc.equals("pointcut1")) {
    //do something.
}
if (pc.equals("pointcut2")) {
    //do something.
}
// ...

}

请建议!!

请更多建议!!!

1 个答案:

答案 0 :(得分:1)

执行此操作的最佳方法是为每个组件切入点编写建议,并设置一个标记表明已到达。由于Aspect优先级(即 - 在其他建议之前运行哪个建议),您需要确保组件建议在词法上高于最终的建议。它看起来像这样:

boolean pointcut1Reached = false;

ModelAndView around(HttpServletRequest request) : pointcut1(request) {
    pointcut1Reached = true;
    try {
         proceed(request);
    } finally {
         pointcut1Reached = false;
    }
}

// ... similar for other pointcuts

@Around("pointcut1(request) || pointcut2(request) || pointcut3(request)")
public ModelAndView myAspect(ProceedingJoinPoint proceedingJp, HttpServletRequest request){
    if (pointcut1Reached) {
        //do something.
    }
    if (pointcut2Reached) {
        //do something.
    }
    // ...
}

这里有两点需要注意:

  1. 如果您的程序是多线程的,那么您将需要确保方面的实例化是合适的。
  2. 我使用代码风格的AspectJ语法,因为我对注释风格有个人偏见。 :)

  3. 要避免多线程代码的问题,可以为方面指定实例化模型。

    aspect MyAspect percflowbelow( execution ( * * HttpServletRequest.something(..) ) { ... }
    

    上面的声明说,在调用HttpServletRequest.something()之后,每个cflow都会实例化一个方面实例。如果在方面内部达到了其中一条建议,但它不在percflow下方,那么建议将不会运行。

    现在唯一的技巧是找出应该在percflowbelow内放置什么样的切入点。在包含所有切入点的堆栈中是否有一些方法调用方式?

    一旦弄明白,你就不用担心多线程了。