Spring AOP - pointcut/interceptor не вызывается

Я определил следующий перехватчик:

@Aspect
public class OpenSessionInRequestInterceptor {

    private Log log = LogFactory.getLog(getClass());

    @Autowired
    private SessionFactory sessionFactory;

    public OpenSessionInRequestInterceptor() {

    }

    @Around("@annotation(com.sc2.master.aop.hibernate.OpenSession)")
    public Object processAround(ProceedingJoinPoint pjp) throws Throwable {
        log.info("Opening Hibernate Session in method "+pjp.getSignature());
        Session session = SessionFactoryUtils.getSession(sessionFactory, true);
        TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));

        Object ret = pjp.proceed();

        session.close();
        TransactionSynchronizationManager.unbindResource(sessionFactory);

        log.info("Closing Hibernate Session in method "+pjp.getSignature());

        return ret;
    }

}

Когда я выполняю следующий фрагмент кода в весеннем тесте

    @OpenSession
    public void call() {
        BusinessCustomer customer = (BusinessCustomer) this.customerDao.loadAll().get(0);
        System.out.println(customer.getContacts().size());
    }

вызывается метод аспекта. Чтобы начать тест, мой тестовый класс выглядит следующим образом:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:WebContent/WEB-INF/applicationContext.xml"})
@Transactional

Однако, когда у меня есть метод, аннотированный @OpenSession, и я развертываю приложение на своем сервере Tomcat, метод перехватчика не вызывается.

Определение контекста приложения выглядит следующим образом:

<aop:aspectj-autoproxy proxy-target-class="true">
</aop:aspectj-autoproxy>

<bean id="openSessionInRequestInterceptor" class="OpenSessionInRequestInterceptor"></bean>

Я совершенно не могу понять, почему АОП не работает при развертывании на коте. Надеюсь, у вас есть идеи.

Решение Я нашел решение. Я помещаю свою конфигурацию aop в applicationContext.xml, но это не сработает. Я поместил конфигурацию в application-servlet.xml, и теперь все в порядке. Кто-нибудь знает, почему?


person Erik    schedule 05.04.2011    source источник


Ответы (2)


Я признаю, что мне не нужно было заставлять его работать с помощью аннотации маркера, но мне нужна была аннотация в качестве аргумента, так что это сработало:

@Around("@annotation(foo)")
public Object invoke(ProceedingJoinPoint invocation, Foo foo) throws Throwable 

Но... обратите внимание, что @Transactional также запускает сеанс, если он не запущен, поэтому, возможно, вам это не нужно.

Обновление: если ваши bean-компоненты определены в дочернем контексте, то конфигурация aop родительского контекста не влияет на них. Родительский контекст не видит дочерний контекст, а ваш x-servlet.xml является дочерним контекстом.

person Bozho    schedule 05.04.2011
comment
Если я изменю сигнатуру метода на public Object processAround(ProceedingJoinPoint pjp, OpenSession openSession) throws Throwable, я получу исключение: Вызвано: java.lang.IllegalArgumentException: ошибка в::0 формальная несвязанная в pointcut. - person Erik; 05.04.2011
comment
@Erik - но также измените @annotation(foo) - так что там нет полного доменного имени, только имя параметра. - person Bozho; 05.04.2011
comment
Хорошо, теперь программа компилируется, но аспект не вызывается. Есть ли какая-то регистрация/отладка, которую можно было бы использовать, чтобы увидеть, что происходит? - person Erik; 05.04.2011
comment
Ясно... так есть ли передовая практика, где разместить конфигурацию aop? - person Erik; 05.04.2011
comment
@Erik - обычно все идет в основном контексте. И вам редко нужен aop на веб-слое. - person Bozho; 05.04.2011

Чтобы ответить, почему вам нужно поместить конфигурацию в XML-файл сервлета, чтобы начать работу:

Я предполагаю, что вы используете тег <context:component-scan ...>, и он помещается в XML-файл сервлета. Вот почему вам нужно иметь их обоих в сервлете XML, иначе они не «видят» друг друга. В результате соединение не устанавливается должным образом.

person conan_z    schedule 07.03.2014