Spring AOP получает значение аннотации

Я использую Spring AOP, как я могу получить значения из аннотации. Вот моя аннотация:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
@Documented
public @interface ExecutionMethodProfiler 
{
    String value() default "defaultValue";;
}

вот мой XML:

<aop:aspectj-autoproxy/>
    <aop:config>
        <aop:aspect ref="methodProfiler">
            <aop:pointcut id="serviceMethod" 
                expression="(execution(* com.old..*(..)) or execution(* com.test..*(..))) and @annotation(com.test.profiler.ExecutionMethodProfiler)" />
            <aop:around pointcut-ref="serviceMethod" method="profile"/>
        </aop:aspect>
    </aop:config>

И это мой сервисный метод:

public void profile(ProceedingJoinPoint jointPoint) throws Throwable {}

на данный момент я могу получить значения, используя этот код:

MethodSignature signature = (MethodSignature) jointPoint.getSignature();
System.out.println(signature.getMethod().getAnnotation(ExecutionMethodProfiler.class).value());

Мне это не нравится, есть ли лучший способ?


person Michael Biniashvili    schedule 14.01.2017    source источник


Ответы (1)


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

public void profile(
    ProceedingJoinPoint jointPoint,
    ExecutionMethodProfiler methodProfiler
) throws Throwable {}

Затем привяжите аннотацию к этому аргументу в вашем pointcut:

<aop:around
    pointcut="(execution(* com.old..*(..)) or execution(* com.test..*(..))) and @annotation(methodProfiler)"
    method="profile"
    arg-names="methodProfiler"
/>

На самом деле я не проверял это, потому что сейчас немного занят, но в основном это так.

person kriegaex    schedule 18.01.2017
comment
Я пробую это, и я получаю сообщение об ошибке: вложенное исключение - java.lang.IllegalArgumentException: ошибка в:: 0 формальный несвязанный в pointcut - person Michael Biniashvili; 22.01.2017
comment
Я обновил свой ответ, чтобы параметр точки соединения был первым в сигнатуре метода. В AspectJ это может быть первый или последний параметр, но, возможно, Spring здесь более придирчив. Кроме того, убедитесь, что имя параметра везде одинаковое: pointcut, arg-names и подпись метода. В противном случае он не может быть связан. - person kriegaex; 22.01.2017
comment
Если я обновляю сигнатуру метода, я получаю это исключение: Исключение конструктора; вложенным исключением является java.lang.IllegalStateException: ожидается найти 2 аргумента для привязки по имени в совете, но на самом деле найден 1 аргумент. - person Michael Biniashvili; 22.01.2017
comment
Было бы проще использовать аннотацию @Around непосредственно в вашем коде и сделать класс @Aspect вместо использования старомодной конфигурации XML, которая также затрудняет сопоставление pointcut и его рекомендаций. Но если вы хотите продолжить этот путь, возможно, вам поможет что-то вроде arg-names="joinPoint,methodProfiler". Я понятия не имею. Вероятно, полезно либо поэкспериментировать, либо прочитать Руководство Spring по АОП. - person kriegaex; 22.01.2017
comment
Я использую конфигурацию xml, потому что мне нужно загружать этот aspact только в среде производительности/разработки, мне не нужно, чтобы он был активен в производстве, с помощью xml мне легче выбрать, когда загружать aop - person Michael Biniashvili; 22.01.2017