Spring AOP - @Before не выполняется

Я пытаюсь реализовать простой пример Spring AOP (v4), используя совет @Before с выражением pointcut на месте, но метод аспекта не вызывается. У меня есть все необходимые зависимости (весна-аоп, аопаллианс, аспектвейвер). Что я делаю неправильно?

package com.xyz;

public class TestClass {
    @PostConstruct
    public void init() {
        test();
    }
    public void test() {
       ...
    }
}

Аспект:

@Aspect
@Component
public class MyAspect{
    @Before("execution(* com.xyz.TestClass.test())")
    public void beforeTest() {
       ...      
    }
}

person user1491636    schedule 25.05.2016    source источник
comment
Вы включили прокси-сервер Spring Auto? Как вы создали экземпляр TestClass?   -  person Ali Dehghani    schedule 26.05.2016
comment
TestClass — это bean-компонент, определенный в контексте моего приложения. Он проходит через жизненный цикл, когда приложение запускается, но pointcut никогда не срабатывает. У меня также есть <aop:aspectj-autoproxy /> в контексте приложения. Что-нибудь еще требуется?   -  person user1491636    schedule 26.05.2016


Ответы (1)


Причина, по которой АОП не выполняется, заключается в том, что TestClass.test() не вызывается в контексте Spring, а имеет простой/простой вызов из TestClass.init().

Чтобы проверить свою настройку, измените ее на что-то похожее на приведенное ниже, чтобы вызов TestClass.test() управлялся spring

package com.xyz;

public class TestClass {

   public void test() {
     ...
   }
}

Вставьте TestClass в другой класс, скажем, AnotherTestClass, и вызовите оттуда метод test

package com.xyz;

public class AnotherTestClass {

   @Autowired
   private TestClass testClass;

   public void anotherTest() {
     testClass.test();
   }
}
person Bond - Java Bond    schedule 28.05.2016
comment
В моем примере TestClass — это управляемый bean-компонент Spring. Это определило мой контекст приложения. Разве этого недостаточно? - person user1491636; 30.05.2016
comment
Нет, как я упоминал в своем ответе, для перехвата TestClass.test() его следует вызывать через другой компонент. Простой вызов в пределах того же bean-компонента не запускает зарегистрированные аспекты. - person Bond - Java Bond; 31.05.2016
comment
Java Bond, Есть ли другой вариант? TestClass нельзя подключить автоматически. Однако я могу сделать его bean-компонентом (определенным в контексте приложения), который устанавливается через конструктор AnotherTestClass (другой bean-компонент, определенный в контексте приложения). Есть ли способ заставить его работать с данной настройкой? Спасибо! - person user1491636; 31.05.2016
comment
Если оба bean-компонента определены в одном и том же контексте, вы можете их автоматически связать. Какая-то конкретная причина, по которой вы думаете, что этого не может быть? - person Bond - Java Bond; 31.05.2016
comment
Не вдаваясь в подробности, это просто природа bean-компонентов и приложения. - person user1491636; 31.05.2016
comment
Не кажусь грубым, честно говоря, странно, что bean-компоненты, определенные в одном контексте, не могут быть автоматически подключены. К сожалению, из-за небольшого количества доступной информации не так много вариантов, которые можно изучить. - person Bond - Java Bond; 31.05.2016