Antes de leer este artículo, puede consultar el artículo " Comprensión simple del COI y AOP de Spring y ejemplos de código " para comprender brevemente el contenido relevante de COI y AOP. Vamos al tema.
Este artículo creará el ejemplo más simple paso a paso para usar las características de AOP de Spring, que se considera una demostración para principiantes de Spring AOP. Como principiante, la ejecución de una demostración tan simple también ha sido golpeada por muchas dificultades.
Problema de OOP, complementario a AOP
Cuando necesitamos introducir el comportamiento público en objetos dispersos, OOP parece impotente. Es decir, OOP le permite definir relaciones de arriba a abajo, pero no es adecuada para definir las relaciones de izquierda a derecha. Por ejemplo, función de registro. El código de registro a menudo se dispersa horizontalmente en todos los niveles de objeto sin ninguna relación con la funcionalidad central del objeto al que está disperso. Lo mismo es cierto para otros tipos de código, como seguridad, manejo de excepciones y transparencia. Este tipo de código irrelevante disperso en todas partes se llama código transversal. En el diseño de OOP, causa mucha duplicación de código, que no es propicio para la reutilización de cada módulo.
El llamado "aspecto", en pocas palabras, encapsula la lógica o las responsabilidades que no están relacionadas con el negocio, pero que el módulo de negocios llaman conjuntamente, lo que facilita la reducción de la duplicación de código del sistema, reduciendo el acoplamiento entre módulos y promover la operabilidad futura y la mantenimiento.
Soporte para AOP en primavera
El agente AOP en primavera es responsable de la generación y la gestión de los contenedores del COI de Spring, y sus dependencias también son administradas por los contenedores del COI. Por lo tanto, el proxy AOP puede dirigirse directamente a otras instancias de frijoles en el contenedor, y esta relación se puede proporcionar mediante la inyección de dependencia del contenedor del COI. Spring usa Java Dynamic Proxy para crear AOP proxy de forma predeterminada, para que pueda crear proxy para cualquier instancia de interfaz. Cuando la clase que necesita un proxy no es una interfaz proxy, Spring cambiará automáticamente a usar proxy CGLIB, y también puede forzar CGLIB.
La lógica de este ejemplo es la siguiente: hay una clase de automóvil (clase ejecutiva). Antes y después de que se ejecute el método GO en la clase de automóvil, habrá registros de registro correspondientes, pero la clase de automóvil en sí no conoce ninguna lógica del registro.
Crear un proyecto maven y agregar dependencias
Primero, cree un nuevo proyecto Maven, use la plantilla MavenerchetypequickStart, luego abra el archivo pom.xml y agregue los paquetes de dependencia requeridos para que se ejecute Spring AOP.
<Spendency> <MoupRoMID> org.springframework </groupid> <artifactid> spring-core </artifactid> <verserse> 4.0.5.release </versión> </pendency> <epardency> <proupid> org.springframework </proupid> <artifactid> spring-beans </artifactid>>> <versión> 4.0.5.release </verververs> </pendency> <pendency> <grupid> org.springframework </groupid> <artifactid> spring-Context </artifactid> <ververy> 4.0.5.release </verversion> </dependency> <epartency> <uproupid> org.springframework </proupid> <artifactid> springcontex <versión> 4.0.5.release </verververs> </pendency> <epardency> <grupid> org.springframework </groupid> <artifactid> spring-aop </artifactid> <verververs> 4.0.5.release </ververy> </dependency> <epardent> <proupid> org.aspectj </proupid> <tartifactid> spective </art de/arthifactid> <Versión> 1.8.1 </versión> </pendency>
Escribir código de negocio
Se agregó un automóvil de clase ejecutiva, incluido un método Go ()
paquete com.wowo.spring_aop_demo1; public class Car {public void go () {System.out.println ("¡Go Go Go!"); }}Escribir facetas
La clase de registro registrará el funcionamiento del sistema, pero la lógica de registro no se escribirá en todas partes en la clase ejecutiva, sino que existe como una clase facetal.
paquete com.wowo.spring_aop_demo1; public class Carlogger {public void befeforUnun () {System.out.println ("El automóvil va a ejecutarse"); } public void AfterRun () {System.out.println ("El automóvil está ejecutando"); }}Esta clase de aspecto contiene dos métodos, a saber, la pre-notificación y la postnotificación.
Configurar asociaciones a través de frijoles
Se agregó un nuevo archivo de configuración, llamado bean.xml en este ejemplo, para asociar la cara y las notificaciones en el archivo de configuración
<? xml versión = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" "" "" xmlns: p = "http://www.springframework.org/schema/p" xmlns: context = "http://www.springframework.org/schema/context" xmlns: aop = "http://www.springframework.org/schema/schema/" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/contextExt http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframe.org/schema/aop/spring-aop.xsd ">" <bean id = "logger" /> <aop: config> <aop: aspecto ref = "logger"> <aop: pointCut Expression = "Execution (* com.wowo.spring_aop_demo1.car.go (..))" id = "Go" /> <aop: antes de punto-refut-ref = "go" Method = "beForerun" /> <aop: Method = "AfterRun"/> </aop: aspecto> </aop: config> </beans>
Nota: En este archivo de configuración, se requiere el espacio de nombres de AOP y varias direcciones contenidas en XSI: Schemalocation.
Ejecución (* com.wowo.spring_aop_demo1.car.go (..)) es una expresión de corte de puntos de aspectoj. La ejecución significa activar durante la ejecución. El siguiente * representa el valor de retorno de cualquier tipo. com.wowo.spring_aop_demo1.car se refiere a la clase donde se encuentra el corte de puntos. Go (..) es el nombre del método, y ... representa cualquier parámetro.
Hay 5 tipos de notificaciones que se pueden aplicar a las secciones de resorte:
・Antes: se llama a la notificación de llamada antes del método
・Después, se llama a una notificación después de completar el método, independientemente de si el método se ejecuta con éxito.
・Después de retorno: se llama a la notificación de llamada después de que el método se ejecuta con éxito
・Después de lanzar: llamar la notificación después de que el método lanza una excepción
・Alrededor de los paquetes de noidad el método notificado y realiza un comportamiento personalizado antes y después de la llamada del método notificado.
Ejecutar el código de negocio
A continuación se muestra una clase que contiene el método Main () para ejecutar el código de negocio
paquete com.wowo.spring_aop_demo1; import org.springframework.context.applicationContext; import org.springframework.context.support.classpathxmlapplicationContext; public class App {public static void main (string [] args) {AplusionContext = New ClasspathxmlaPplicationContext ("bean.xml"); Coche de coche = (coche) context.getBean ("coche"); carga(); }}En el código anterior, la primavera crea un objeto de automóvil. Cuando Spring crea este objeto, encuentra que uno de sus métodos está configurado como PointCut. Por lo tanto, al instanciar el objeto, se creará un objeto proxy. Cuando se ejecuta el método de corte de punto (), será interceptado por el objeto proxy creado por Spring. Antes de ejecutar el método GO, llamará al preprocesamiento correspondiente del preprocesado correspondiente de Carlogger BeForRun (), luego llame al método Car.Go () y luego llame al post-procesos de la clase de corte Carlogger afterRun ().
Nota: El resorte debe usarse para crear un objeto que contenga tangentes. Si lo crea usted mismo, Spring no puede monitorearlo y su operación no se notificará aplicando ninguna aplicación.
El resultado de salida del proyecto es
¡El coche va a ir a ir!
Usar notificaciones envolventes
Si desea utilizar notificaciones envolventes, necesitamos modificar los métodos de notificación y los archivos de configuración en la clase de aspecto. La clase ejecutiva no necesita hacer modificaciones porque están completamente desacopladas. Primero modifique la clase de la clase Carlogger
importar org.spectj.lang.procedingjoinpoint; public class Carlogger {public void alrededor de RUN (procedimientoJoinpoint unePoint) {System.out.println ("El automóvil se ejecutará"); Pruebe {// llamando al método de destino del objeto proxy, en este ejemplo apuntando al método car.go () unkenpoint.proced (); } catch (Throwable E) {E.PrintStackTrace (); } System.out.println ("El automóvil se está ejecutando"); }}El método que rodea la notificación debe aceptar los parámetros de tipo procedimientojoinpoint, y su método Process () llamará al método de destino del objeto proxy, por lo que en circunstancias normales, se debe llamar a este método. También podemos organizar la ejecución del objeto proxy al no llamar a este método.
A continuación, modifique la parte de configuración AOP: Configuración del archivo de configuración a lo siguiente
<aop: config> <aop: aspecto ref = "logger"> <aop: pointCut Expression = "Ejecution (* com.wowo.spring_aop_demo1.car.go (..))" id = "go"/> <aop: method = "alrededor de" alrededor "PointCut-ref =" Go "/> </aop: Aspecto> </aop: configuración>
Nota: Las notificaciones envolventes no pueden existir al mismo tiempo que las notificaciones delantera/posterior. Después de ejecutar el código, el resultado de salida permanece sin cambios.
Resumir
Lo anterior es todo el contenido compartido por este artículo sobre la introducción a la demostración de Spring AOP, espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!