【问题标题】:Spring Aop Error Can not build thisJoinPoint lazily for this adviceSpring Aop Error Can not build thisJoinPoint lazy for this advice
【发布时间】:2014-01-05 04:35:02
【问题描述】:

切入点声明:

@Pointcut(value="com.someapp.someservice.someOperation() && args(t,req)",argNames="t,req")
private void logOperationArg(final String t,final String req)
{
}

建议声明未编译:

@Before(value="logOperationArg(t,req)")
public void logBeforeOperationAdvice(JoinPoint jp, final String t, final String req){
...
}

使用 Aspectj-maven-plugin(1.5 版本)编译 Aspect 时,出现错误 "can not build thisJoinPoint lazily for this advice since it has no suitable guard [Xlint:noGuardForLazyTjp]"

但同样的建议在没有 JoinPoint 参数的情况下也可以编译。

建议声明编译:

@Before(value="logOperationArg(t,req)")
public void logBeforeOperationAdvice(final String t, final String req){
...
}

【问题讨论】:

  • 如何执行 logOperationArg()?将其公开...同时使用 execution() 而不是 value=...

标签: java spring spring-aop aspectj-maven-plugin


【解决方案1】:

Spring AOP 仅支持method join points,因为它基于dynamic proxies,如果需要,它会创建代理对象(例如,如果您使用ApplicationContext,它将在从BeanFactory 加载bean 后创建)

使用execution() 语句匹配作为方法执行的连接点。

例如:

class LogAspect {

@Before("execution(* com.test.work.Working(..))")
public void beginBefore(JoinPoint join){

System.out.println("This will be displayed before Working() method will be executed");
}

现在如何声明你的 BO:

//.. declare interface

然后:

class BoModel implements SomeBoInterface {

public void Working(){
System.out.println("It will works after aspect");
     }
}

execution() 语句是一个切入点表达式,用于告诉您的建议应该应用到哪里。

如果你喜欢使用@PointCut,你可以这样做:

class LogAspect {

//define a pointcut
@PointCut(
        "execution(* com.test.work.SomeInferface.someInterfaceMethod(..))")
     public void PointCutLoc() {
}

@Before("PointCutLoc()")
public void getBefore(){
System.out.println("This will be executed before someInterfaceMethod()");
      }

}

第二部分:

此外,错误表明您没有对您的建议采取保护措施。从技术上讲,guard 使您的代码更快,因为您不需要在每次执行时都构造 thisJoinPoint。所以,如果它没有意义,你可以尝试忽略它

canNotImplementLazyTjp = ignore
multipleAdviceStoppingLazyTjp=ignore
noGuardForLazyTjp=ignore

【讨论】:

  • 根据 Spring AOP doc docs.spring.io/spring/docs/3.0.x/reference/… 切入点声明也可以使用方法名来完成
  • 它可以,如果你在像@AfterThrowing这样的注释中使用它,但你没有这样做。因此,您应该使用 execution() 语句来表达您的切入点并匹配您的连接点。因此 execution() 将获取您的方法名称(包含所有路径),以了解在哪里应用您的建议。 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多