以下の注釈があります。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
public class SomeAspect{
@Around("execution(public * *(..)) && @annotation(com.mycompany.MyAnnotation)")
public Object procede(ProceedingJoinPoint call) throws Throwable {
//Some logic
}
}
public class SomeOther{
@MyAnnotation("ABC")
public String someMethod(String name){
}
}
上記のクラスでは、「[〜#〜] abc [〜#〜] "in @ MyAnnotation」を渡します。 「[〜#〜] abc [〜#〜] value in procede method of SomeAspect.Java class?」にアクセスするにはどうすればよいですか?
ありがとう!
ProceedingJoinPoint から Signature を取得でき、メソッド呼び出しの場合は MethodSignature にキャストするだけです。
_@Around("execution(public * *(..)) && @annotation(com.mycompany.MyAnnotation)")
public Object procede(ProceedingJoinPoint call) throws Throwable {
MethodSignature signature = (MethodSignature) call.getSignature();
Method method = signature.getMethod();
MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
}
_
ただし、最初に注釈属性を追加する必要があります。サンプルコードにはコードがありません。
_@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
}
_
その後、あなたはそれにアクセスすることができます
_MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
String value = myAnnotation.value();
_
[〜#〜] edit [〜#〜]
クラスレベルで@MyAnnotation( "ABC")がある場合に値を取得する方法は?
Class
は AnnotatedElement
でもあるため、Method
と同じ方法で取得できます。例えば。メソッドの宣言クラスの注釈は、次を使用して取得できます。
_ Method method = ...;
Class<?> declaringClass = method.getDeclaringClass();
MyAnnotation myAnnotation = declaringClass.getAnnotation(MyAnnotation.class)
_
スプリングを使用しているため、スプリングの AnnotationUtils.findAnnotation(..)
を使用することもできます。 springと同じように注釈を検索します。例えば。また、スーパークラスやインターフェイスメソッドなども調べます。
_ MyAnnotation foundAnnotation = AnnotationUtils.findAnnotation(method, MyAnnotation.class);
_
実際、ProceedingJoinPointからだけでなく、別の方法でvalue
を取得できると思います。 reflection
。
アノテーションを直接使用して、次のように試してください。com.mycompany.MyAnnotation yourAnnotation
にadvice params
を追加し、@Around
に@annotation(yourAnnotation)
を追加します。
@Around("execution(public * *(..)) && @annotation(yourAnnotation)")
public Object procede(ProceedingJoinPoint pjp, com.mycompany.MyAnnotation yourAnnotation) {
...
yourAnnotation.value(); // get your annotation value directly;
...
}
アドバイスパラメータのcom.mycompany.MyAnnotation
は、
@Around("execution(public * *(..)) && @annotation(com.mycompany.MyAnnotation)")
yourAnnotation
は、paramsのMyAnnotation
がどの注釈であるべきかを既に示しているため、有効な変数名になります。ここで、yourAnnotation
は、注釈インスタンスのみを取得するために使用されます。
さらにパラメータを渡したい場合は、args()
を試してください。
詳細については、公式の doc を確認してください。注釈値については、@Auditable
を検索するだけです。
これも機能します-クラスのリフレクションを使用して、注釈情報を取得できます。
Annotation anno = MyClass.class.getAnnotation(MyAnnotation.class);
または
Annotation anno = MyClass.class.getDeclaredMethod("somethod").getAnnotation(MyAnnotation.class);
これは、正しく宣言されている注釈が実行時に使用可能な場合にのみ機能します。
@Retention(RetentionPolicy.RUNTIME)
AspectJ/AOPを使用して、メソッドアノテーションとクラスレベルアノテーションの作業コードを検索する
@Around("execution(* com.first.test.controller..*(..)))")
public Object profileAllMethods(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
{
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
Java.lang.reflect.Method method = methodSignature.getMethod();
Annotation []methodAnnotations = method.getDeclaredAnnotations();
System.out.println("==============="+methodAnnotations[0].toString());
Annotation []classAnnotations = proceedingJoinPoint.getTarget().getClass().getAnnotations();
System.out.println("===Class Annotation : "+classAnnotations[1].toString());
Object result = proceedingJoinPoint.proceed();
return result;
}
René'sの例は長い道のりを歩んでいます。また、ClassLevel注釈を取得する方法の説明。
しかし、以前に「* @ Around( "execution(public *(..))&& @annotation(com.mycompany。 MyAnnotation) ")" "
どうすればこれを回避できますか?メソッド実行を経由せずにClassLevelアノテーションが設定されている場合、どのようにしてアスペクトをトリガーできますか?
のようなClassLevelアノテーションを書きたい
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.METHOD, ElementType.TYPE })
@EnableSwagger2
@Import(SwaggerConfiguration.class)
public @interface EnableSwaggerApi {
String controllerPackage() default "foo.bar.ctrl";
}
「controllerPackage」の値を受け取りたい「SwaggerConfiguration」に関する構成をインポートしています
@Aspect
public class SwaggerConfiguration {
@Value("${tom.swagger.controller.package:foo.bar.notset}")
private String controllerPackage;
@Value("${tom.swagger.api.version:1.0.0}")
private String apiVersion;
@Value("${spring.application.name:MyApplication}")
private String applicationName;
@Around("execution(public * *(..)) && @annotation(EnableSwaggerApi)")
public void procede(ProceedingJoinPoint call) throws Throwable {
MethodSignature signature = (MethodSignature) call.getSignature();
Method method = signature.getMethod();
Class<?> declaringClass = method.getDeclaringClass();
EnableSwaggerApi myAnnotation = declaringClass.getAnnotation(EnableSwaggerApi.class);
System.err.println("1 -> " + myAnnotation.controllerPackage()); // -> tko.backend.spring.ctrl
myAnnotation = method.getAnnotation(EnableSwaggerApi.class);
System.err.println("2 -> " + myAnnotation.controllerPackage()); // -> tko.backend.spring.SOMEOTHERSTUFF
// THIS WORKS, BUT JUST IF I USE THE @EnableSwaggerApi ON SOME METHOD!
// NOT ON CLASS
}
@Bean
public Docket swaggerApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("controllerPackage"))
.paths(PathSelectors.any())
.build()
.apiInfo(new ApiInfoBuilder().version(apiVersion).title(applicationName).description("Documentation " + applicationName + " API v" + apiVersion)
.build());
}
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/v2/api-docs", config);
return new CorsFilter(source);
}
}
@EnableSwaggerApi(controllerPackage="tko.backend.spring.ctrl")
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class, Initializer.class);
}
@Bean
@EnableSwaggerApi(controllerPackage="tko.backend.spring.SOMEOTHERSTUFF")
public String initSwagger() {
return "some dummy";
}
}
initSwagger()の注釈を削除するにはどうすればよいですか? Application.classはSwaggerConfiguration(Swagger Stuff別のライブラリで)私は次のような単純なリフレクションを使用することはできません
Application.class.getAnnotation(EnableSwaggerApi.class)