1. Préface
Dans les projets précédents, j'ai rarement prêté attention à la mise en œuvre et à la théorie spécifiques du printemps AOP. J'ai juste bien compris ce qu'est AOP et comment l'utiliser. J'ai vu un article de blog bien écrit, alors je suis venu l'apprendre.
AOP
AOP (programmation orientée vers l'aspect), c'est-à-dire la programmation orientée vers l'aspect, peut être considérée comme un supplément et une amélioration de la POO (programmation orientée objet). La POO introduit des concepts tels que l'encapsulation, l'héritage et le polymorphisme pour établir une hiérarchie d'objets qui est utilisée pour simuler une collection de comportement public. Cependant, la POO permet aux développeurs de définir les relations verticales, mais ne convient pas pour définir des relations horizontales, telles que les fonctions de journalisation. Le code journal est souvent dispersé horizontalement dans tous les niveaux d'objets et n'a rien à voir avec les fonctions centrales de l'objet correspondant. Ce type de code non lié dispersé partout est appelé coupe croisée. Dans la conception OOP, il provoque une grande quantité de duplication de code, qui n'est pas propice à la réutilisation de chaque module.
La technologie AOP, au contraire, utilise une technique appelée "coupe croisée" pour disséquer l'intérieur d'un objet encapsulé et encapsuler les comportements courants qui affectent plusieurs classes dans un module réutilisable et le nommer "Aspect", qui est la facette. La soi-disant «section» est simplement encapsulée par la logique ou les responsabilités qui ne sont pas liées à l'entreprise mais qui sont appelées conjointement par le module commercial, ce qui est pratique pour réduire le code en double du système, réduire le couplage entre les modules et propice à l'opérabilité future et à la maintenabilité.
En utilisant la technologie "transversal", AOP divise le système logiciel en deux parties: préoccupation principale et préoccupation croisée. Le principal processus de traitement commercial est l'objectif principal, et la partie qui a peu à voir avec elle est l'objectif transversal. Une caractéristique des préoccupations croisées est qu'ils se produisent souvent dans plusieurs préoccupations de base, et sont fondamentalement similaires à divers endroits, tels que l'authentification de l'autorisation, les journaux et les choses. Le rôle de l'AOP est de séparer diverses préoccupations dans le système et de séparer les principales préoccupations des préoccupations croisées.
Concept de base AOP
1. Points d'attention croisés
Quelles méthodes intercepter et comment y faire face après l'interception? Ces préoccupations sont appelées préoccupations croisées
2. Section (aspect)
Les classes sont des abstractions des caractéristiques des objets, et les sections sont des abstractions de préoccupations croisées
3. JOINPOINT
Le point intercepté, car Spring ne prend en charge que les points de connexion de type méthode, de sorte que le point de connexion dans Spring fait référence à la méthode interceptée. En fait, le point de connexion peut également être un champ ou un constructeur.
4. Pointcut
Définition des points de connexion interceptant
5. Notification (conseils)
La soi-disant notification fait référence au code à exécuter après avoir intercepté le point de connexion. Les notifications sont divisées en cinq catégories: prédéfini, post-set, exception, final et notifications environnantes.
6. Objet cible
L'objet cible du proxy
7. tisser
Le processus d'application d'une fente à un objet cible et de provoquer la création d'objets proxy
8. Introduction
Sans modifier le code, l'introduction peut ajouter dynamiquement certaines méthodes ou champs à la classe pendant la période d'exécution
Le support du printemps pour AOP
L'agent AOP du printemps est responsable de la génération et de la gestion du conteneur IOC de Spring, et ses dépendances sont également gérées par le conteneur IOC. Par conséquent, le proxy AOP peut cibler directement d'autres instances de haricots dans le conteneur, et cette relation peut être fournie par injection de dépendance du conteneur IOC. Les règles de création d'un proxy au printemps sont:
1. Par défaut, Java Dynamic Proxy est utilisé pour créer un proxy AOP, afin que vous puissiez créer un proxy pour toute instance d'interface.
2. Lorsque la classe qui a besoin d'un proxy n'est pas une interface proxy, le ressort passera à l'utilisation du proxy CGLIB et peut également forcer CGLIB à utiliser.
La programmation AOP est en fait une chose très simple. En regardant la programmation AOP, les programmeurs n'ont qu'à participer à trois parties:
1. Définir les composants commerciaux ordinaires
2. Définir le point d'entrée, un point d'entrée peut croiser plusieurs composants commerciaux
3. Définir le traitement amélioré. Le traitement amélioré est l'action de traitement qui est tissée en composants commerciaux ordinaires dans le cadre AOP.
Par conséquent, la clé de la programmation AOP est de définir le point d'entrée et de définir le traitement d'amélioration. Une fois le point d'entrée et le traitement d'amélioration appropriés définis, le cadre AOP générera automatiquement un proxy AOP, c'est-à-dire la méthode d'objet proxy = traitement d'amélioration + méthode d'objet proxy.
Voici un modèle de fichier Spring AOP .xml nommé AOP.xml, et le contenu suivant est élargi sur aop.xml:
<? xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemalation = "http://www.spring http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> </ beans>
Implémentation simple d'AOP basée sur le printemps
Notez qu'avant d'expliquer, permettez-moi d'expliquer: Pour exécuter avec succès le code, il ne suffit pas d'utiliser le package JAR fourni par Spring au développeur. Veuillez télécharger deux packages en pot en ligne:
1. Aopalliance.jar
2. Aspectjwweaver.jar
Commençons à expliquer la méthode d'implémentation XML de Spring AOP, définissons d'abord une interface:
Interface publique Helloworld {void printheLelloworld (); void doprint ();} Définissez deux classes d'implémentation d'interface:
classe publique HelloworldIMPL1 implémente Helloworld {public void printheLelloworld () {System.out.println ("Entrez HelloworldImpl1.printHelloworld ()"); } public void doprint () {System.out.println ("Entrez helloworldImpl1.doprint ()"); retour ; }} classe publique HelloworldIMPL2 implémente Helloworld {public void printheLelloworld () {System.out.println ("Entrez HelloworldImpl2.printHelloworld ()"); } public void doprint () {System.out.println ("Entrez HelloworLDIMPL2.Doprint ()"); retour ; }} Focus croisé, voici le temps d'impression:
classe publique TimeHandler {public void printtime () {System.out.println ("currentTime =" + System.currentTimeMillis ()); }} Avec ces trois classes, vous pouvez implémenter un simple Spring AOP. Jetez un œil à la configuration d'AOP.xml:
<? xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemalation = "http://www.spring http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd"> <bean id="helloWorldImpl1" /> <bean id="helloWorldImpl2" /> <bean id="timeHandler" /> <aop:config> <aop:aspect id="time" ref="timeHandler"> <aop:pointcut id = "addallMethod" expression = "EXECUTION (* com.xrq.aop.helloworld. * (..))" /> <aop: avant méthode = "printtime" Pointcut-ref = "addallMethod" /> <aop: after metheth = "printtime" Pointcut-ref = "addallMethod" /> </ aop: aspect> </ aop: config> </ beebrans>
Écrivez une fonction principale pour l'appeler:
public static void main (String [] args) {applicationContext ctx = new ClassPathXmlApplicationContext ("aop.xml"); Helloworld hw1 = (helloworld) ctx.getBean ("helloworldIMPL1"); Helloworld hw2 = (helloworld) ctx.getBean ("helloworldIMPL2"); HW1.printHelloworld (); System.out.println (); hw1.doprint (); System.out.println (); System.out.println (); HW2.printHelloworld (); System.out.println (); hw2.doprint ();} Le résultat en cours est:
CurrentTime = 14461296119993enter HelloworldImpl1.printHelloworld () CurrentTime = 1446129611993CurrentTime = 1446129611994enter HelloworlDIMPL1.DOPRINT () HelloworldImpl2.printhelloworld () currentTime = 1446129611994currentTime = 1446129611994enter HelloworldIMPL2.Doprint () CurrentTime = 1446129611994
J'ai vu que toutes les méthodes des deux classes d'implémentation de l'interface Helloworld ont été ajoutées au proxy, et le contenu proxy est le temps d'impression.
Détails supplémentaires sur l'utilisation de l'AOP basée sur le printemps
1. Ajoutez une préoccupation croisée et imprimez le journal. La classe Java est:
classe publique Loghandler {public void LogBefore () {System.out.println ("log avant la méthode"); } public void logafter () {System.out.println ("log après la méthode"); }}<? xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemalation = "http://www.spring http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <bean id =" helloworldimpl1 "/> <bean id =" helloworldImpl2 "/> <bean id =" TimeHandler "/> <Bean id =" Loghandler "/> <aop: config> <aop:" reflé order = "1"> <aop: Pointcut id = "addtime" expression = "Execution (* com.xrq.aop.helloworld. * (..))" /> <aop: avant méthode = "printtime" Pointcut-ref = "addtime" /> <aop: after method = "printtime" Pointcut-ref = "addtime" /> </ aop: Ref = "LOGHANDLER" ORDER = "2"> <AOP: Pointcut id = "printLog" expression = "Execution (* com.xrq.aop.helloworld. * (..))" /> <aop: avant méthode = "LogBefore" Pointcut-ref = "printlog" /> <aop: après méthode = "logafter" Pointcut-ref = "printlog" /> </ APECT> "LOGAFTER" </aop: config> </ beans>
La classe de test reste inchangée et le résultat d'impression est:
CurrentTime = 1446130273734log avant Methofenter HelloworldIMPL1.printHelloworld () se connecter après méthodecurrentTime = 1446130273735CurrentTime = 1446130273736log avant Methodenter HelloworldIMPL1.DOPRINT () Log après méthodecurrentTime = 1446130273736CUR 1446130273736log avant MethodineSter HelloworldImpl2
Il existe deux façons d'utiliser le Loghandler avant le TimeHandler:
(1) Il y a un attribut d'ordre dans l'aspect, et le nombre de l'attribut de commande est l'ordre de réduction des points de mise au point
(2) Définissez le Loghandler avant le TimeHandler. Spring utilise l'ordre de définition de l'aspect comme ordre de tissage par défaut.
2. Je veux juste tisser certaines méthodes dans l'interface
Modifiez simplement l'expression de la coupe ponctuelle:
<? xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: aop = "http://www.springframework.org/schema/aop" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemalation = "http://www.spring http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd "> <bean id =" helloworldimpl1 "/> <bean id =" helloworldImpl2 "/> <bean id =" TimeHandler "/> <Bean id =" Loghandler "/> <aop: config> <aop:" reflé Order = "1"> <aop: Pointcut id = "addtime" expression = "EXECUTION (* com.xrq.aop.helloworld.print * (..))" /> <aop: avant méthode = "printtime" Pointcut-ref = "addtime" /> <aop: after method = "printtime" pointcut-ref = "addtime" /> </ aop: Ref = "LOGHANDLER" ORDER = "2"> <AOP: Pointcut id = "printLog" expression = "EXECUTION (* com.xrq.aop.helloworld.do * (..))" /> <aop: avant méthode = "LogBefore" Pointcut-ref = "printlog" /> <aop: after method = "Logafter" Pointcut-ref = "printlog" /> </ APECTMENT> "LOGAFTER" </aop: config> </ beans>
Cela signifie que TimeHandler ne tirera que des méthodes qui commencent au début de l'interface Helloworld, Logandler ne fera que tisser des méthodes qui commencent au début de l'interface Helloworld
3. Forcer Cglib à générer un proxy
Comme mentionné précédemment, Spring utilise Dynamic Proxy ou CGLIB pour générer un proxy. Des versions plus élevées de Spring choisiront automatiquement d'utiliser un proxy dynamique ou un CGLIB pour générer du contenu proxy. Bien sûr, nous pouvons également forcer CGLIB à générer un proxy, c'est-à-dire qu'il existe un attribut "proxy-citelle" dans <aop: config>. Si cette valeur d'attribut est définie sur true, le proxy basé sur la classe fonctionnera. Si la classe de cible proxy est définie sur False ou si cet attribut est omis, le proxy basé sur l'interface fonctionnera.
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.