programing

ProceedingJoinPoint에서 메서드의 주석 값을 가져오려면 어떻게 해야 합니까?

newsource 2022. 9. 21. 00:05

ProceedingJoinPoint에서 메서드의 주석 값을 가져오려면 어떻게 해야 합니까?

아래에 주석이 있습니다.

My Annotation.자바

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

}

SomeAspect.java

public class SomeAspect{

 @Around("execution(public * *(..)) && @annotation(com.mycompany.MyAnnotation)")
    public Object procede(ProceedingJoinPoint call) throws Throwable {

  //Some logic

}

}

SomeOther.java

public class SomeOther{

@MyAnnotation("ABC") 
public String someMethod(String name){


}


}

위 수업에서는 @MyAnnotation에서 "ABC"를 전달하고 있습니다.SomeAspect.java 클래스의 프로시저 메서드의 "ABC" 값에 액세스하려면 어떻게 해야 합니까?

감사합니다!

시그니처ProceedingJoinPoint에서 얻을 수 있으며 메서드 호출의 경우 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();

편집

클래스 레벨에 @MyAnnotation("ABC")이 있는 경우 값을 얻는 방법

A Class이기도 합니다.따라서, 에서는, 와 같은 방법으로 취득할 수 있습니다.Method예: 메서드의 선언 클래스에 대한 주석을 얻을 수 있습니다.

 Method method = ...;
 Class<?> declaringClass = method.getDeclaringClass();
 MyAnnotation myAnnotation = declaringClass.getAnnotation(MyAnnotation.class)

봄을 사용하고 있기 때문에 봄의 것도 사용하는 것이 좋을지도 모릅니다.스프링과 마찬가지로 주석을 검색합니다.예를 들어 슈퍼클래스 및 인터페이스 메서드 등을 검토한다.

 MyAnnotation foundAnnotation = AnnotationUtils.findAnnotation(method, MyAnnotation.class);

편집

또한 5.2에서 소개된 봄의 기능에 관심이 있을 수 있습니다.

사실, 난 우리가 이 모든 걸 수중에valueProceeding Join Point를 사용하는 것이 아니라 다른 방식으로 진행됩니다.reflection.

주석을 직접 사용하여 다음과 같이 시도합니다.com.mycompany.MyAnnotation yourAnnotation당신의 안에서advice params그리고.@annotation(yourAnnotation)@Around.

@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이후 유효한 변수 이름이 될 수 있습니다.MyAnnotationparams는 이미 어떤 주석이 되어야 하는지를 나타내고 있습니다.여기서yourAnnotation는 주석 인스턴스만 가져오는 데 사용됩니다.

더 많은 매개 변수를 통과하고 싶다면args().

자세한 내용은 공식 문서를 참조하십시오.주석 값의 경우 검색만 하면 됩니다.@Auditable.

이 작업도 가능합니다.클래스의 리플렉션으로 주석 정보를 취득할 수 있습니다.

Annotation anno = MyClass.class.getAnnotation(MyAnnotation.class);

아니면

Annotation anno = MyClass.class.getDeclaredMethod("somethod").getAnnotation(MyAnnotation.class);

이는 올바르게 선언한 런타임에 주석을 사용할 수 있는 경우에만 작동합니다.

@Retention(RetentionPolicy.RUNTIME)

르네의 예는 나를 멀리 데려가고 있다.ClassLevel Annotations를 얻는 방법에 대해서도 설명합니다.

그러나 이전에 "*@Around("execution (public * (..)" & @annotation (com.mycompany)" 메서드 주석을 사용한 경우에만 ClassLevel Annotations Values를 읽을 수 있습니다.My Annotation)"

어떻게 하면 이 문제를 피할 수 있을까요?메서드 실행을 거치지 않고 클래스 레벨 주석이 설정된 경우 어떻게 애스펙트를 트리거할 수 있습니까?

ClassLevel 주석을 다음과 같이 쓰고 싶다.

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.METHOD, ElementType.TYPE })
@EnableSwagger2
@Import(SwaggerConfiguration.class)
public @interface EnableSwaggerApi {
    String controllerPackage() default "foo.bar.ctrl";
}

"controller Package" 값을 받을 "Swagger Configuration"에 대한 구성을 가져옵니다.

@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는 Swagger Configuration(Swagger Stuff는 별도 lib에 있음)에 인식되지 않기 때문에 다음과 같은 간단한 리플렉션을 사용할 수 없습니다.

Application.class.getAnnotation(EnableSwaggerApi.class)

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;
    }

문서에 설명된 대로 메서드를 바인딩할 수 있습니다.

My Annotation.자바

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

}

SomeAspect.java

public class SomeAspect{

 @Around("execution(public * *(..)) && @annotation(myAnnotation)")
    public Object procede(ProceedingJoinPoint call, MyAnnotation myAnnotation) throws Throwable {

  //Some logic

  }
}

언급URL : https://stackoverflow.com/questions/21275819/how-to-get-a-methods-annotation-value-from-a-proceedingjoinpoint