Spring 3.0 aop Pointcut格式不正确:期待'名称模式'错误

时间:2010-09-30 15:50:52

标签: java spring aop aspectj spring-aop

以下是我的切入点和建议声明

//PointCut on A method which takes two parameters and is in a DAO
@Pointcut("execution(backend.repository.QuestionsRepository.AnswerQuestion (..))")
public void answerQuestionPointCut() {}


@Around(
   value="web.activity.advisors.UserActivityAdvisor.answerQuestionPointCut()",
   argNames="question,answer"
)

 // Do something

}

我收到以下错误

Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting 'name pattern' at character position 65
execution(backend.repository.QuestionsRepository.AnswerQuestion (..))
                                                                 ^

坚持这个,任何指针

3 个答案:

答案 0 :(得分:15)

您缺少返回类型:

@Pointcut("execution(* backend.repository.QuestionsRepository.AnswerQuestion (..))")

你必须绑定参数名称,如下所示:

@Pointcut("execution(* backend.repository.QuestionsRepository.AnswerQuestion (..)) 
&& args(question, answer)") // wrapped for readability only

示例解决方案

服务界面:

package foo.bar.service;
public interface Service{
    void whack(String thing, Integer thang);
}

实施班级:

package foo.bar.service;
public class DefaultService implements Service{
    @Override
    public void whack(final String thing, final Integer thang){
        System.out.println(
            "Inside thing: " + thing + ", inside thang: " + thang
        );
    }
}

Spring AOP方面:

@Aspect
public class ServiceAspect{

    @Pointcut("execution(* foo.bar.service.*.*(..))")
    public void serviceMethodExecution(){
    }

    @Around(value = "serviceMethodExecution() && args(param1, param2)")
    public void aroundServiceMethodExecution(final ProceedingJoinPoint pjp,
        final String param1,
        final Integer param2) throws Throwable{

        System.out.println("Before thing: " + param1 + ", before thang: "
            + param2);
        pjp.proceed();
        System.out.println("After thing: " + param1 + ", after thang: "
            + param2);
    }

}

Spring Context XML:

<aop:aspectj-autoproxy proxy-target-class="false"  />
<bean class="foo.bar.service.DefaultService" />
<bean class="foo.bar.aspects.ServiceAspect" />

测试的主要类别:

现在这是测试整个过程的主要方法。它启动了Spring ApplicationContext ,没有XML配置,上面的XML定义了服务bean和方面(事实证明,没有XML的解决方案只能工作,因为我开启了AspectJ编织,我不知道我必须包含哪些bean来启用aspectj-autoproxy,所以我现在使用ClassPathXmlApplicationContext这个最小的XML):

public static void main(final String[] args){
    final ApplicationContext applicationContext =
        new ClassPathXmlApplicationContext("classpath:/aspectContext.xml");
    final Service service = applicationContext.getBean(Service.class);
    service.whack("abc", 123);
}

<强>输出:

Before thing: abc, before thang: 123
Inside thing: abc, inside thang: 123
After thing: abc, after thang: 123

这应该让你开始。基本上:如果使用JDK代理(默认为spring),则需要检查您正在拦截的方法是否由服务接口支持。请在此处阅读Spring AOP proxy mechanisms

注意:

如您所见,我将方法参数绑定到方面,而不是切入点,因此可以为具有不同参数签名的方法重用切入点。但是也可以在切入点中绑定它们,如下所示:

@Pointcut(value = "execution(* foo.bar.service.*.*(..)) && args(a,b)",
          argNames = "a,b")
public void serviceMethodExecution(final String a, final Integer b){
}

@Around(value = "serviceMethodExecution(param1, param2)",
        argNames = "param1,param2")
public void aroundServiceMethodExecution(final String param1,
    final Integer param2,
    final ProceedingJoinPoint pjp) throws Throwable{

    System.out.println("Before thing: " + param1 + ", before thang: "
        + param2);
    pjp.proceed();
    System.out.println("After thing: " + param1 + ", after thang: "
        + param2);
}

答案 1 :(得分:1)

你应该这样写

@Pointcut("execution(* backend.repository.QuestionsRepository.AnswerQuestion (..))")

注意"... (* backend..."

* 应该使用空格。

答案 2 :(得分:1)

请注意,@Before中的org.aspectj.lang.annotation.Before注释具有类似的行为。

您可以使用不带执行关键字且没有返回类型的表达式:

@Before("allGetters()")

或同时使用:

@Before("execution(public * allGetters())")

但是如果不使用返回类型,则无法使用execution关键字。