How to get a method's annotation value from a ProceedingJoinPoint?

后端 未结 5 1584
谎友^
谎友^ 2020-12-12 15:41

I have below annotation.

MyAnnotation.java

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

}
         


        
5条回答
  •  猫巷女王i
    2020-12-12 15:57

    René's example is taking me a long way. Also the explanation how I get ClassLevel Annotations.

    But then I can only read ClassLevel Annotations Values if I have previously used a method annotation with "*@Around("execution(public * (..)) && @annotation(com.mycompany.MyAnnotation)")""

    How can I get around this? How can I trigger an Aspect if a ClassLevel Annotation is set without going through a Method Execution?

    I want to write a ClassLevel Annotation like

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

    It's importing the Configuration about "SwaggerConfiguration" where I want to receive the value of "controllerPackage"

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

    How can I can rid of the annotation on initSwagger()? Since the Application.class is not known to SwaggerConfiguration (Swagger Stuff it's in a separate lib) I can't use simple reflection like

    Application.class.getAnnotation(EnableSwaggerApi.class)
    

提交回复
热议问题