Как насчет этого?
@Pointcut(
"within(@org.springframework.stereotype.Controller *) || " +
"within(@org.springframework.web.bind.annotation.RestController *)" +
)
Или немного короче, но, возможно, слишком нечетко, если в пакетах Springs есть другие классы с совпадающими именами (я не проверял):
@Pointcut("within(@(org.springframework..*Controller) *)")
Обновление: Что касается вашего реального вопроса, я понял его теперь после вашего редактирования. Это тоже возможно, но синтаксически сложно. Позвольте мне переименовать ваши аннотации в MetaAnnotation
и MyAnnotation
, хорошо? Поскольку они на самом деле не являются родительскими и дочерними друг для друга, в смысле ООП нет наследования, а только вложение.
Аннотации:
Убедитесь, что аннотации действительно имеют область выполнения. Я не видел этого в вашем коде.
package de.scrum_master.app;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({ TYPE })
public @interface MetaAnnotation {}
package de.scrum_master.app;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({ TYPE })
@MetaAnnotation
public @interface MyAnnotation {}
Примеры классов Java:
Один класс аннотируется метааннотацией, один - аннотированной аннотацией, а третий - без аннотации (отрицательный тестовый пример):
package de.scrum_master.app;
@MetaAnnotation
public class MyClassA {
public void doSomething() {}
}
package de.scrum_master.app;
@MyAnnotation
public class MyClassB {
public void doSomething() {}
}
package de.scrum_master.app;
public class MyClassC {
public void doSomething() {}
}
Приложение драйвера:
Поскольку я использую чистый Java + AspectJ без Spring, я использую это небольшое приложение, чтобы продемонстрировать результат.
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
new MyClassA().doSomething();
new MyClassB().doSomething();
new MyClassC().doSomething();
}
}
Аспект:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MetaAnnotationInterceptor {
@Before(
"execution(* *(..)) && (" +
"within(@de.scrum_master.app.MetaAnnotation *) || " +
"within(@(@de.scrum_master.app.MetaAnnotation *) *)" +
")"
)
public void myAdvice(JoinPoint thisJoinPoint){
System.out.println(thisJoinPoint);
}
}
Журнал консоли:
execution(void de.scrum_master.app.MyClassA.doSomething())
execution(void de.scrum_master.app.MyClassB.doSomething())
Теперь, если вы хотите добавить еще один уровень вложенности, добавьте новую аннотацию и аннотируйте ею ранее не аннотированный класс:
package de.scrum_master.app;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({ TYPE })
@MyAnnotation
public @interface MyOtherAnnotation {}
package de.scrum_master.app;
@MyOtherAnnotation
public class MyClassC {
public void doSomething() {}
}
Затем расширьте pointcut еще на один уровень вложенности / рекурсии:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class MetaAnnotationInterceptor {
@Before(
"execution(* *(..)) && (" +
"within(@de.scrum_master.app.MetaAnnotation *) || " +
"within(@(@de.scrum_master.app.MetaAnnotation *) *) || " +
"within(@(@(@de.scrum_master.app.MetaAnnotation *) *) *)" +
")"
)
public void myAdvice(JoinPoint thisJoinPoint){
System.out.println(thisJoinPoint);
}
}
Журнал консоли изменится на:
execution(void de.scrum_master.app.MyClassA.doSomething())
execution(void de.scrum_master.app.MyClassB.doSomething())
execution(void de.scrum_master.app.MyClassC.doSomething())
P.S .: Часть execution(* *(..))
необходима только в AspectJ, чтобы ограничить сопоставление pointcut выполнением методов, потому что AspectJ может перехватывать больше событий, чем Spring AOP. Таким образом, в Spring AOP вы можете удалить эту часть и скобки, окружающие ... || ... || ...
часть.
person
kriegaex
schedule
31.01.2018