Spring 3.0 Aop Pointcut не правильно сформирован: ожидание ошибки 'name pattern' - PullRequest
9 голосов
/ 30 сентября 2010

Следующее - мой pointcut и совет объявления

//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 ]

15 голосов
/ 30 сентября 2010

Вам не хватает типа возврата:

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

Пружинный аспект АОП:

@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, определяющим компонент службы и аспект (оказывается, что решение без 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 .

Примечание:

Как вы видите, я связываю аргументы метода с аспектом, а не с точечным вырезом, поэтому делаю повторное использование точечного для методов с разными сигнатурами аргументов. Но было бы также возможно связать их в pointcut, как это:

@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 голос
/ 06 июня 2016

Обратите внимание, что у вас аналогичное поведение с аннотацией @Before в org.aspectj.lang.annotation.Before.

Вы можете использовать выражение без ключевого слова выполнение и без типа возврата:

@Before("allGetters()")

или с обоими:

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

, но вы не можете использовать ключевое слово execution без использования типа возвращаемого значения.

1 голос
/ 01 апреля 2012

Вы должны написать так

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

обратите внимание на "... (* backend..."

* и следует использовать пробел.

...