Spring AOP: совет по аннотации используется поверх другого совета
Я создал свою собственную аннотацию:
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Condition {
String value();
}
Я хочу использовать эту аннотацию, чтобы определить, следует ли запустить совет, моя попытка:
@Condition("some.config")
@Around("execution(public * someMethod())")
Object doSomething(ProceedingJoinPoint joinPoint) throws Throwable {
// some logic here
}
@Around("@annotation(condition)")
Object checkCondition(ProceedingJoinPoint joinPoint, Condition condition) throws Throwable {
String property = (String) configuration.getProperty(condition.value());
if (Boolean.valueOf(property)){
return joinPoint.proceed();
} else {
return null;
}
}
Работает когда использую @Condition
на некоторых других методах, т.е. checkCondition
применяется, а затем метод выполняется или не на основе значения конфигурации. За советом doSomething
это не применяется, хотя.
1 ответ
Вы сказали, что ваш аспект работает для других компонентов, но не для самого аспекта. Из этого заявления я понимаю, что
- ваш аспект подключен правильно (например, помечены
@Component
и обнаружен при сканировании компонента или подключен вручную через XML-конфигурацию) и - Вы используете Spring AOP на основе прокси.
В (2) источник вашей проблемы. Согласно руководству Spring сами аспекты освобождаются от того, чтобы сами быть аспектными объектами:
Консультирование аспектов с другими аспектами?
В Spring AOP невозможно, чтобы сами аспекты были целью советов других аспектов. Аннотация @Aspect для класса помечает его как аспект и, следовательно, исключает его из автоматического проксирования.
Таким образом, М. Прохоров в некоторой степени ошибается, когда говорит, что аспекты не являются (или не могут быть) компонентами Spring, но он прав, поскольку по своему замыслу вы не можете самостоятельно советовать какой-либо аспект или советовать другим аспектам. Его предположение, что оно может работать с AspectJ, также верно. Он работает с AspectJ, поэтому, если вам это нужно, вы можете настроить Spring для использования AspectJ через LTW вместо Spring AOP для этого случая.