Valeurs d'annotations Java fournies de manière dynamique
Je veux fournir des annotations avec certaines valeurs générées par certaines méthodes.
J'ai essayé jusqu'à présent:
public @interface MyInterface {
String aString();
}
@MyInterface(aString = MyClass.GENERIC_GENERATED_NAME)
public class MyClass {
static final String GENERIC_GENERATED_NAME = MyClass.generateName(MyClass.class);
public static final String generateName(final Class<?> c) {
return c.getClass().getName();
}
}
Pensée GENERIC_GENERATED_NAME
est static final
il se plaint de ce que
La valeur de l'annotation attribut
MyInterface.aString
doit être une expression constante
Donc comment faire ?
source d'informationauteur thelost
Vous devez vous connecter pour publier un commentaire.
Il n'existe aucun moyen pour générer dynamiquement une chaîne de caractères utilisée dans une annotation. Le compilateur évalue l'annotation des métadonnées pour
RetentionPolicy.RUNTIME
annotations au moment de la compilation, maisGENERIC_GENERATED_NAME
n'est pas connue jusqu'à ce que l'exécution. Et vous ne pouvez pas utiliser des valeurs générées pour les annotations qui sontRetentionPolicy.SOURCE
parce qu'ils sont jetés après le temps de compilation, de sorte que ceux générés valeurs jamais être connu.La solution est d'utiliser une méthode annotée à la place. Appelez la méthode (avec réflexion) pour obtenir la valeur dynamique.
À partir de la perspective de l'utilisateur, nous aurions:
L'annotation elle-même serait défini comme
La mise en œuvre de la recherche pour deux de ces annotations est plutôt simple.
Il n'y a aucun moyen de modifier les propriétés d'une annotation dynamiquement comme les autres ont dit. Si vous voulez le réaliser, il y a deux façons de le faire.
Affecter une expression à la propriété dans l'annotation et au processus d'expression chaque fois que vous récupérez l'annotation. Dans votre cas, votre annotation peut être
@MyInterface(aString = "objectA.doSomething(args1, args2)")
Quand vous avez bien lu, vous pouvez les processus de la chaîne et de faire l'invocation de la méthode et d'en récupérer la valeur. Le printemps n'est que par SPEL (Printemps expression de la langue). C'est consommatrice de ressources et les cycles de processeur sont gaspillés chaque fois que nous voulons processus de l'expression. Si vous utilisez le printemps, vous pouvez le brancher dans un beanPostProcessor et processus de l'expression et de stocker le résultat quelque part. (Soit un mondial des propriétés de l'objet ou dans une carte qui peut être récupéré à n'importe où).
Le chemin du jdk magasins de l'annotation de la carte est dépendant de la version de java et n'est pas fiable, car il n'est pas exposé à l'utilisation (c'est privé).
Vous pouvez trouver une implémentation de référence ici.
https://rationaleemotions.wordpress.com/2016/05/27/changing-annotation-values-at-runtime/
P. S: je n'ai pas essayé et testé la deuxième méthode.