J'ai une annotation J'ai de l'aspect et de la Guice à ma disposition. La seule solution que j'ai proposée jusqu'à présent consiste à utiliser Guice pour injecter une instance Singleton de l'annotation code> à un aspect, qui recherche toutes les classes annotées avec Exemple de pseudo-code simplifié de Ma solution: P> @myannotation code> et je peux annoter tout type (classe) avec elle. Ensuite, j'ai une classe appelée
AnnotateClassregister Code> et j'aimerais qu'il enregistre toutes les classes annotées avec
@myannotation code> afin que je puisse y accéder plus tard. Et j'aimerais enregistrer ces classes automatiquement lors de la création du
annotéclassregister code> si possible, et surtout avant que les classes annotées ne soient instanciées.
@myannotation code> et il Ajoute le code nécessaire pour enregistrer une telle classe dans son constructeur. L'inconvénient de cette solution est que j'ai besoin d'instancier chaque classe annotée pour que le code ajouté par AOP soit réellement exécuté, je ne peux donc pas utiliser l'instanciation paresseuse de ces classes. P>
// This is the class where annotated types are registered
public class AnnotatedClassRegister {
public void registerClass(Class<?> clz) {
...
}
}
// This is the aspect which adds registration code to constructors of annotated
// classes
public aspect AutomaticRegistrationAspect {
@Inject
AnnotatedClassRegister register;
pointcutWhichPicksConstructorsOfAnnotatedClasses(Object annotatedType) :
execution(/* Pointcut definition */) && args(this)
after(Object annotatedType) :
pointcutWhichPicksConstructorsOfAnnotatedClasses(annotatedType) {
// registering the class of object whose constructor was picked
// by the pointcut
register.registerClass(annotatedType.getClass())
}
}
5 Réponses :
Ce n'est pas simple que beaucoup est sûr, mais je le ferais de manière pure Java: p>
.Class code> faire un class.forname () code> pour obtenir l'objet de la classe li>
- Lisez l'annotation par réflexion. Si c'est présent, stockez la classe dans une liste ou définir li>
ul>
Les aspects ne vous aideront pas là-bas, car les aspects ne fonctionnent que sur le code qui est réellement exécuté. P>
mais Annotation Le traitement peut être une option, créer un processeur qui enregistre toutes les classes annotées et crée une classe qui fournit une liste de ces classes p>
Merci pour votre réponse! Mais que se passe-t-il si je n'ai pas de fichier jar? C'est une application Web en cours d'exécution sur Tomcat dans le répertoire EXploDed WAR CODE>. Je vais regarder dans le traitement de l'annotation pendant ce temps ..
@Equi Dans ce cas, utilisez la réponse de Peter, qui est une légère variation de la mine qui fonctionnera également avec des fichiers de guerre éclatés (ou utilisez le traitement de l'annotation)
Le traitement de l'annotation semble que cela ferait ce que je veux, mais cela a besoin de moi pour spécifier quelles classes à traiter et que je ne sais pas avant l'exécution. J'ai trouvé cela Nice article qui explique comment le traitement peut être le traitement Exécuter de manière programmable à partir du code Java, mais comment puis-je traiter toutes les classes de la classe de classe de l'application Web?
@Equi Mais cela a besoin de moi pour spécifier les classes à traiter i> Nope. La seule chose que vous devez savoir est quelle annotation à rechercher. Vous ne pouvez pas exécuter le traitement de l'annotation à partir du conteneur Web. APT fonctionne sur des sources, non compilées de cours, cela fait partie du processus de construction.
+1 pour élargir mes horizons parce que je ne savais pas qu'une telle chose que le traitement de l'annotation existait même. Je donnerais un autre +1 pour vos explications, mais je ne peux pas :) Quoi qu'il en soit, je l'ai eu bien fonctionnant grâce au code Snippet @Peter. Merci à vous deux!
Il est possible: p>
Obtenez tous les chemins dans une classe de classe. Parse Utilisez system.geproperties (). GetProperty ("java.class.path", null) code> pour obtenir tous les chemins. P> li>
classloader.getresources (chemin) code> Pour obtenir toutes les ressources et vérifier les cours: http://snippets.dzone.com/posts/show/4831 p> li>
ol>
L'extrait de code que vous avez posté m'a aidé et il semble que ce que je cherche! Merci!
Lien brisé (mai / 2017)
Eh bien, si votre De cette façon, vous n'avez pas besoin de rechercher toutes ces classes, elles seront enregistrées juste avant d'être utilisées. Notez que cela ne fonctionnera que pour les cours qui sont instanciés par Guice. P> annotéclassregister.registerclass () code> ne doit pas être appelé immédiatement à
annotéclassregister code> temps de création, mais cela pourrait attendre jusqu'à ce qu'une classe soit d'abord instanciée, Ensuite, je envisagerais d'utiliser une Guice
Typelistener code>, enregistrée avec un correspondeur code> qui vérifie si une classe est annotée avec
@myannotation code>. p>
J'utiliserais la staticialisation () code> PointeCut dans AspectJ et amendez des cours à votre registre car ils sont chargés, comme:
after() : staticinitialization(@MyAnnotation *) {
register.registerClass(thisJoinPointStaticPart.getSignature().getDeclaringType());
}
Vous pouvez utiliser le ClassGraph CODE>
Emballez comme:
Java: p> scala: p>
A-t-il besoin d'être exécuté ou pouvez-vous faire la liste à la compilation?
Il doit être à l'exécution car c'est une fonctionnalité de cadre. Les utilisateurs du cadre utiliseront l'annotation pour annoter leurs classes et le cadre doit faire tout le travail sale pour les enregistrer lorsque la demande est lancée.
D'accord, mais l'Assemblée pourrait encore être faite au moment de la compilation, tant que le cadre sait comment le trouver au moment de l'exécution, non?
Eh bien, les implémentations JPA le font à l'exécution des classes annotées avec @enttity etc. Utilisent-ils un moyen standard commun de récupérer toutes les classes annotées ou vérifient-ils tout le chargeur de classe pour eux?