Аспект вокруг совета не срабатывает на контроллере
У меня есть совет по аспектам, который отслеживает выполнение классов, аннотированных @Service. Код в настоящее время работает, но я хотел бы изменить его так, чтобы он отслеживал конечные точки REST на контроллерах вместо сервисов с автоматической связью Вот код:
@Aspect
public class AuditingAspect
{
@Pointcut(
//TODO Change pointcut from public methods in Services to REST endpoints in Controllers
"execution(public * my.base.package..*.*(..))" //Must be in package
//+ " && @within(org.springframework.stereotype.Service)" //Has to be a service
+ " && @within(org.springframework.stereotype.Controller)" //Has to be a controller
)
public void auditLoggingPointCut() {
//no op
}
@Around(value ="auditLoggingPointCut()")
public Object logAround(final ProceedingJoinPoint joinPoint) throws Throwable
{
System.out.println("Exection");
returnVal = joinPoint.proceed();
// Now Do The After Logging Part
afterReturningLog(joinPoint, returnVal) ;
return returnVal;
}
private void afterReturningLog(final JoinPoint joinPoint, final Object returnValue)
{
System.out.println("Exiting");
}
}
Когда я изменяю "inside" с @Service на @Controller, я не вижу никаких выводов из совета, но метод выполняется при доступе из URL. Чем отличается контроллер, который будет игнорировать выполнение?
Класс Controller выглядит следующим образом:
@Controller
public class CaseReferralEndpoints {
@Autowired
CaseReferralFacade caseReferralFacade;
@RequestMapping(value="/backgroundcheck/getcasereferrals", method = RequestMethod.GET)
@ResponseBody
public List<CaseReferralSection> getCaseReferrals(@RequestParam("caseID") Long caseID) {
return caseReferralFacade.getCaseReferrals(caseID);
}
}
Вот мое приложение Context-aop.xml. Полная конфигурация намного больше, но я считаю, что это наиболее актуально.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean class="gov.dhs.uscis.elis2.backend.services.logging.AuditingAspect"/>
<aop:aspectj-autoproxy proxy-target-class="false" />
</beans>
4 ответа
Предположим, что ваша конфигурация @within верна, потенциальное решение ваших проблем будет следующим:
<aop:aspectj-autoproxy proxy-target-class="true" />
Также вам нужно будет добавить CGLIB в ваш classpath
Вышеуказанные шаги необходимы, так как ваш контроллер не реализует интерфейс
Наконец, если у вас есть корневой контекст и веб-контекст, то относящиеся к AOP вещи должны быть применены к веб-контексту (наличие его в корневом контексте не будет работать для контроллеров, настроенных в веб-контексте)
ОБНОВИТЬ
В Gradle для добавления CGLIB в путь к классам добавьте:
'cglib:cglib:2.2.2'
В Maven это будет:
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
Обнаружена ошибка внутри applicationContext.xml
Мои контроллеры были отфильтрованы от контекстного сканирования! Я один из многих разработчиков проекта, поэтому я не думал, что искать здесь изначально.
<context:component-scan>
<!-- a bunch of packages -->
<context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>
Однако в итоге я добавил Interceptor, который оказался ближе к тому, что я хотел. Поскольку все наши пользовательские действия основаны на REST, было проще и понятнее контролировать вызовы REST, чем пытаться отслеживать методы автосопровождения.
Как ваше выражение pointcut имеет
@within(org.springframework.stereotype.Service)
с символом && совет будет применяться только в вашем пакете до услуги.
и я надеюсь, что ваш класс контроллера не внутри ..Сервисный пакет, он может быть внутри.*.* Пакет контроллера, поэтому он не выполняется для контроллера
решение Удалить изнутри точки срез выражения
или добавить контроллер также внутри выражения среза точки
Предполагая, что ваш pointcut правильный, и вы используете два пружинных контекста, один для services/daos (appcontext) и один для контроллеров (servletcontext), мой совет идет в направлении неверной конфигурации.
Конфигурация AOP является одним из пружинных компонентов, которые применяются ТОЛЬКО в контексте, который объявлен / отсканирован.
Итак, если у вас есть servletcontext.xml для ваших контроллеров, ваши pointcut не будут применены, если вы не объявите конфигурацию контекста aop в этом контексте.
(Объявление контекста приложения понадобится, если вы хотите применить pointcuts к вашим службам.)