【问题标题】:spring 3.0 aop Pointcut is not well-formed: expecting 'name pattern' errorspring 3.0 aop 切入点格式不正确:期待“名称模式”错误
【发布时间】:2010-09-30 15:50:52
【问题描述】:

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

//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 (..))
                                                                 ^

我坚持这个,任何指针

【问题讨论】:

    标签: java spring aop aspectj spring-aop


    【解决方案1】:

    您缺少返回类型:

    @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 上下文 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);
    }
    

    【讨论】:

    • Thnaks,我猜 a) 意味着这个 @Pointcut("execution(*backend.repository.QuestionsRepository.AnswerQuestion (..)) && args(question, answer)") public void answerQuestionPointCut(Question question ,回答回答){}
    • 我不知道 b 是什么意思,需要更多指示
    • 切入点格式不正确:期望在字符位置 66 处执行“名称模式”(*backend.repository.QuestionsRepository.AnswerQuestion (..)) && args(question, answer)
    • 非常感谢......让它工作,缺少返回类型和你提到的其他点。 spring 文档真的很混乱
    • 非常感谢 .. 搞定了。别客气。但在这里表示感谢的最佳方式是接受答案。
    【解决方案2】:

    你应该这样写

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

    关注"... (* backend..."

    *应该使用空格。

    【讨论】:

    • 请在发帖前努力阅读以前的答案。
    【解决方案3】:

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

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

    @Before("allGetters()")
    

    或两者兼有:

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

    但是你不能在不使用返回类型的情况下使用execution 关键字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多