Aspectj не улавливает все события в spring framework?
-
09-06-2019 - |
Вопрос
Мой проект основан на spring Framework 2.5.4.И я пытаюсь добавить аспекты для некоторых контроллеров (я использую aspectj 1.5.3).
Я включил автоматический прокси в application-servlet.xml, просто вставил эти строки в конец XML-файла:
<aop:aspectj-autoproxy />
<bean id="auditLogProcessor" class="com.example.bg.web.utils.AuditLogProcessor" />
Созданный аспект:
package com.example.bg.web.utils;
import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class AuditLogProcessor
{
private final static Logger log = Logger.getLogger(AuditLogProcessor.class);
@After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
public void afterHandleRequest() {
log.info("test111");
}
@After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
public void afterRebuildThumbnail() {
log.info("test222");
}
}
Мои контроллеры:
class AssetAddController implements Controller
class AssetThumbnailRebuildController extends MultiActionController
Когда я устанавливаю точки торможения в советниках аспектов и вызываю контроллеры, я перехватываю только afterHandleRequest(), но не afterRebildThumbnail() Что я сделал не так?
ПРИМЕЧАНИЕ
Я задаю этот вопрос от имени моего друга, у которого нет доступа к бета-версии SO, и я понятия не имею, о чем вообще идет речь.
Редактировать
Там действительно были некоторые орфографические ошибки, спасибо Cheekysoft.Но проблема все еще сохраняется.
Решение
Ваши точки останова не достигаются, потому что вы используете AOP-прокси Spring.Видишь понимание-aop-прокси для описания того, в чем особенность прокси-серверов AOP.
По сути, фреймворк MVC собирается вызвать handleRequest
метод на прокси-сервере вашего контроллера (который, например, MultiActionController
вы используете в качестве реализации базового класса), затем этот метод выполнит "внутренний" вызов своего метода rebuildThumbnail, но это не пройдет через прокси и, следовательно, не выявит никаких аспектов.(Это не имеет никакого отношения к тому, что методы являются окончательными.)
Чтобы достичь того, чего вы хотите, исследуйте использование "реального" AOP с помощью load time weaving (который Spring поддерживает очень хорошо).
Другие советы
AspectJ плохо работает с классами в Spring Web MVC framework. Прочтите нижнюю часть поля "Открыть для расширения ..." в правой части страницы
Вместо этого взгляните на Обработчикинтерцептор интерфейс.
Новые аннотации Spring MVC также могут работать, поскольку с тех пор все классы контроллеров являются POJO, но я сам этого не пробовал.
Базовая настройка выглядит нормально.
Синтаксис можно немного упростить, не определяя точечный cut на месте, а просто указав метод, к которому следует применить последующий совет.(Именованные точечные вырезы для методов создаются для вас автоматически.)
например ,
@After( "com.example.bg.web.controllers.assets.AssetAddController.handleRequest()" )
public void afterHandleRequest() {
log.info( "test111" );
}
@After( "com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail()" )
public void afterRebuildThumbnail() {
log.info( "test222" );
}
До тех пор, пока метод rebuildThumbnail не является окончательным, а имя метода и класс указаны правильно.Я не понимаю, почему это не сработает.
видишь http://static.springframework.org/spring/docs/2.0.x/reference/aop.html
Это так же просто, как правописание?или в вопросе просто опечатки?Иногда ты пишешь rebuildThumbnail
и иногда ты пишешь rebildThumbnail
Методы, которые вы пытаетесь переопределить с помощью advice, не являются окончательными методами в среде MVC, поэтому, хотя ответ bpapas полезен, я понимаю, что в данном случае это не проблема.Тем не менее, убедитесь, что rebuildThumbnail
действие контроллера не является окончательным
@bpapas:пожалуйста, поправьте меня, если я ошибаюсь.Собственное действие контроллера программиста - это то, что он пытается переопределить.Рассматривая исходный код MultiActionController (и его родительский), единственным завершенным методом, потенциально находящимся в стеке, является MultiActionController.invokeNamedMethod
, хотя я не уверен на 100%, будет ли это в стеке в то время или нет.Вызовет ли наличие завершенного метода выше по стеку проблему с добавлением рекомендаций AOP к методу, расположенному ниже?