J'ai ci-dessous l'annotation.
@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){
}
}
Dans la classe ci-dessus, je passe "ABC" avec dans @MyAnnotation . Maintenant, comment puis-je accéder à la valeur "ABC" dans procede méthode de SomeAspect.Java class?
Merci!
Vous pouvez obtenir le Signature à partir d'un ProceedingJoinPoint et, dans le cas d'une invocation de méthode, il suffit de le convertir en un 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);
}
Mais vous devez d'abord ajouter un attribut d'annotation. Votre exemple de code n'en a pas, par exemple.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
}
Ensuite, vous pouvez y accéder
MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
String value = myAnnotation.value();
MODIFIER
Comment obtenir de la valeur si j'ai @MyAnnotation ("ABC") au niveau de la classe?
Une Class
est aussi un AnnotatedElement
, vous pouvez donc l'obtenir de la même manière que pour une Method
. Par exemple. Une annotation de la classe déclarante de la méthode peut être obtenue en utilisant
Method method = ...;
Class<?> declaringClass = method.getDeclaringClass();
MyAnnotation myAnnotation = declaringClass.getAnnotation(MyAnnotation.class)
Si vous utilisez le printemps, vous pouvez aussi utiliser le AnnotationUtils.findAnnotation(..)
du printemps. Il recherche une annotation comme le fait le printemps. Par exemple. également à la recherche d'une classe supérieure et de méthodes d'interface, etc.
MyAnnotation foundAnnotation = AnnotationUtils.findAnnotation(method, MyAnnotation.class);
En fait, je pense que nous pouvons obtenir la value
d'une autre manière au lieu de simplement ProceedingJoinPoint, ce qui nous obligera certainement à utiliser reflection
.
Essayez d’utiliser les annotations directement comme suit: ajoutez com.mycompany.MyAnnotation yourAnnotation
dans votre advice params
et @annotation(yourAnnotation)
dans @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
dans les paramètres de conseil fonctionnent comme cela dans
@Around("execution(public * *(..)) && @annotation(com.mycompany.MyAnnotation)")
yourAnnotation
peut être un nom de variable valide car MyAnnotation
dans params indique déjà quelle annotation elle devrait être. Ici, yourAnnotation
est utilisé pour extraire l'instance d'annotation uniquement.
Si vous voulez passer plus de paramètres, vous pouvez essayer args()
.
Pour plus de détails, s'il vous plaît vérifier son officiel doc . Pour la valeur d'annotation, vous pouvez simplement rechercher @Auditable
.
Cela fonctionne aussi. Vous pouvez récupérer les informations sur les annotations en utilisant la réflexion sur la classe.
Annotation anno = MyClass.class.getAnnotation(MyAnnotation.class);
Ou
Annotation anno = MyClass.class.getDeclaredMethod("somethod").getAnnotation(MyAnnotation.class);
Cela ne fonctionne que si votre annotation est disponible au moment de l'exécution, ce que vous avez déclaré correctement.
@Retention(RetentionPolicy.RUNTIME)
_ {René} _ l'exemple me prend beaucoup de temps. Aussi l'explication de la façon dont j'obtiens ClassLevel Annotations.
Mais alors, je ne peux lire les valeurs des annotations ClassLevel que si j'ai déjà utilisé une annotation de méthode avec "* @ Around (" execution (public * (..)) &&annotation (com.mycompany.MyAnnotation) ")" "
Comment puis-je contourner cela? Comment puis-je déclencher un Aspect si une annotation ClassLevel est définie sans passer par une exécution de méthode?
Je veux écrire une annotation ClassLevel comme
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.METHOD, ElementType.TYPE })
@EnableSwagger2
@Import(SwaggerConfiguration.class)
public @interface EnableSwaggerApi {
String controllerPackage() default "foo.bar.ctrl";
}
Il importe la configuration sur "SwaggerConfiguration" où je veux recevoir la valeur de "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";
}
}
Comment puis-je supprimer les annotations sur initSwagger ()? Puisque Application.class n'est pas connu de SwaggerConfiguration (Swagger Stuff c'est dans une bibliothèque séparée), je ne peux pas utiliser une réflexion simple comme
Application.class.getAnnotation(EnableSwaggerApi.class)