Maison  >  Article  >  Java  >  Pourquoi AspectJ n'intercepte-t-il pas les classes et méthodes annotées malgré les annotations d'interface et de méthode avec @Marker ?

Pourquoi AspectJ n'intercepte-t-il pas les classes et méthodes annotées malgré les annotations d'interface et de méthode avec @Marker ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-23 23:02:30554parcourir

Why Doesn't AspectJ Intercept Annotated Classes and Methods Despite Interface and Method Annotations with @Marker?

Émuler l'héritage d'annotations pour les interfaces et les méthodes avec AspectJ

Question :

Malgré l'annotation d'une interface et de méthodes avec @Marker, un aspect AspectJ qui attend pour intercepter les classes et méthodes annotées ne se déclenche pas. Pourquoi AspectJ ne les intercepte-t-il pas ?

Réponse :

L'héritage des annotations en Java a des limites. Les annotations sur les interfaces, les méthodes ou les annotations ne sont pas héritées par l'implémentation de classes, la substitution de méthodes ou les classes utilisant des annotations annotées. Seules les classes héritent des annotations des superclasses si le type d'annotation dans la superclasse porte la méta-annotation @Inherited.

Émulation de l'héritage avec AspectJ :

Étant donné qu'AspectJ fonctionne dans les limites de la JVM, une solution de contournement est nécessaire pour émuler l'héritage d'annotations. Une astuce consiste à écrire un aspect qui ajoute manuellement l'annotation aux classes et méthodes d'implémentation :

<code class="java">public aspect MarkerAnnotationInheritor {
  // Implementing classes should inherit marker annotation
  declare @type: MyInterface+ : @Marker;
  // Overriding methods 'two' should inherit marker annotation
  declare @method : void MyInterface+.two() : @Marker;
}</code>

Cet aspect ajoute l'annotation à l'interface et à toutes les classes et méthodes d'implémentation, éliminant ainsi le besoin d'annotations littérales. sur ces éléments. Avec l'aspect en place, les interceptions AspectJ souhaitées fonctionneront comme prévu.

Alternativement, l'aspect peut être intégré directement dans l'interface :

<code class="java">public interface MyInterface {
  void one();
  void two();

  public static aspect MarkerAnnotationInheritor {
    declare @type: MyInterface+ : @Marker;
    declare @method : void MyInterface+.two() : @Marker;
  }
}</code>

Renommer le fichier en MyInterface.aj permet AspectJ pour reconnaître la définition de l'aspect. Notez que les modificateurs dans la déclaration d'aspect peuvent être omis car les membres imbriqués des interfaces sont implicitement publics static.

Cependant, en raison d'un problème du compilateur AspectJ, static doit être explicitement déclaré pour des raisons de stabilité.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn