web-dev-qa-db-fra.com

Utilisation de procurations dans Spring AOP

Je lis un livre qui parle d'activer le support AspectJ dans Spring AOP.

Ci-dessous, un paragraphe tiré du livre:

Pour activer la prise en charge des annotations AspectJ dans le conteneur Spring IoC, il vous suffit de définir un élément XML vide aop: aspectj-autoproxy dans votre fichier de configuration du bean. Ensuite, Spring créera automatiquement des proxys pour tous vos beans qui correspondent à vos aspects AspectJ.

Dans les cas où les interfaces ne sont pas disponibles ou ne sont pas utilisées dans la conception d'une application, il est possible de créer des proxys en s'appuyant sur CGLIB. Pour activer CGLIB, vous devez définir l'attribut proxy-target-class=true dans <aop:aspectj-autoproxy />.


Je ne parviens pas à obtenir le deuxième paragraphe. Que signifie " les interfaces ne sont pas disponibles ". Quelqu'un peut-il illustrer cela avec un exemple?

22
user2434

Spring AOP utilise des proxys dynamiques JDK ou CGLIB pour créer les proxys pour vos objets cibles.

Selon la documentation de Spring, si votre cible implémente au moins une interface, un proxy dynamique JDK sera utilisé. Cependant, si votre objet cible n'implémente aucune interface, un proxy CGLIB sera créé.

Voici comment vous pouvez forcer la création des proxys CGLIB (définir proxy-target-class = " true "):

 <aop:config proxy-target-class="true">
    <!-- other beans defined here... -->
 </aop:config>

Lorsque vous utilisez AspectJ et son support autopoxy, vous pouvez également forcer les proxys CGLIB. C'est là que le <aop:aspectj-autoproxy> est utilisé et ici aussi la "proxy-target-class" doit être définie sur true :

<aop:aspectj-autoproxy proxy-target-class="true"/>

Veuillez vous référer à la section Mécanismes de proxy de la documentation Programmation orientée aspect avec Spring pour plus de détails.

27
nowaq

Spring préfère utiliser des interfaces pour AOP car il peut utiliser JDK proxies .

Disons par exemple que j'ai une interface MyService

public interface MyService {
    void doSomething();
}

Et une implémentation MyServiceImpl

@Service
public class MyServiceImpl implements MyService {
    public void doSomething() {
        // does something!
    }
}

Si Spring découvre que vous avez configuré des aspects pour MyService, il créera un proxy JDK qui implémente MyService, puis procurera tous les appels via votre bean MyServiceImpl, ajoutant des fonctionnalités d'aspect le cas échéant.

Les proxys JDK fonctionnent en implémentant la même interface que votre objet cible et en lui déléguant des appels; ils ne fonctionnent pas s'il n'y a pas d'interface à implémenter. Dans le cas où vous n'avez pas d'interface comme ci-dessus, Spring doit utiliser une bibliothèque de codes d'octets comme CGLIB pour créer dynamiquement des classes au moment de l'exécution qui incorporent la fonctionnalité d'aspect.

22
stevevls

J'ai trouvé un blog ici qui explique clairement comment fonctionne AOP, Caching & Transaction à l'aide de classes proxy d'exécution.

Lorsque vous ne codez pas à l'interface (en citant la section du blog ' Et si la classe de bean n'implémente aucune interface? '): -

Par défaut, si votre bean n'implémente pas d'interface, Spring utilise l'héritage technique: au démarrage, une nouvelle classe est créée. Il hérite de votre classe de bean et ajoute un comportement dans les méthodes enfants. Afin de générer de tels proxys, Spring utilise une bibliothèque tierce appelée cglib.

7
Kumar Sambhav

Spring AOP utilise largement les proxys comme mécanisme pour implémenter les préoccupations transversales (aspects a.k.a) de manière non intrusive, l'idée est essentiellement d'utiliser les proxies comme des enveloppes qui enrichissent le comportement d'origine, c'est-à-dire ajouter des capacités transactionnelles.

Pour ce faire, il existe deux options, selon que l'objet d'origine implémente ou non une interface.

Dans le premier cas (l'objet d'origine implémente au moins une interface), les capacités de proxy dynamique de l'API de réflexion sont utilisées pour créer un objet proxy qui IMPLÉMENTE identique interfaces que l'objet d'origine et donc le proxy peuvent être utilisés à la place.

Dans le second cas (l'objet d'origine PAS implémente n'importe quelle interface), donc une astuce plus élaborée doit être utilisée, et c'est à ce moment que CGLIB apparaît. Selon la page du projet "CGLIB est utilisé pour étendre Java classe et implémente les interfaces au moment de l'exécution". Dans ce cas, l'astuce consiste à créer un proxy qui ÉTEND l'objet d'origine et peut donc être utilisé à la place.

5
Alejandro