Comment étendre L'annotation Java?
Dans mon projet j'utilise pré-définis annotation @With
:
@With(Secure.class)
public class Test { //....
le code source de @With
:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface With {
Class<?>[] value() default {};
}
je veux écrire des annotations personnalisées @Secure
, qui aura le même effet que @With(Secure.class)
. Comment faire?
et si je fais comme ça? Ça va fonctionner?
@With(Secure.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Secure {
}
5 réponses
à Partir de Java language specification, Chapitre 9.6 Types D'Annotation:
aucune clause d'extension n'est permise. (Les types d'Annotation étendent implicitement
annotation.Annotation
.)
ainsi, vous ne pouvez pas étendre une Annotation. vous devez utiliser un autre mécanisme ou créer un code qui reconnaît et traite votre propre annotation. Spring vous permet de grouper d'autres annotations de Spring dans vos propres annotations personnalisées. mais encore, pas d'extension.
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SuperAnnotation {
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SubAnnotation {
SuperAnnotation superAnnotation();
String subValue();
}
Utilisation:
@SubAnnotation(subValue = "...", superAnnotation = @SuperAnnotation(value = "superValue"))
class someClass { ... }
@With(Secure.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Secure {
}
ça va marcher.
Pour développer sur Muhammad Abdurrahman de la réponse--
@With(Secure.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Secure {
}
Ce n' travail par défaut, mais vous utiliser en conjonction avec le Printemps AnnotationUtils.
Voir ceci AFIN de répondre à pour un exemple.
Vous pouvez utiliser les annotations pour l'annotation comme ceci:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@WithSecurityContext(factory = WithCustomUserSecurityContextFactory.class)
public @interface WithCustomUser {
String username() default "demo@demo.com";
String password() default "demo";
String[] authorities() default {Authority.USER};
}
et définir l'état exact dans son "enfant"
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@WithCustomUser(username = "admin@admin.com",
password = "admin",
authorities = {Authority.USER, Authority.ADMINISTRATOR})
public @interface WithAdminUser {
}
dans ce cas, vous avez une sorte d ' "état" et l'accès aux champs d'annotation des parents via réflexion/aspect.