¿Para qué se utiliza Spring Aop?
AOP
Se puede decir que AOP (Programación orientada a aspectos), es decir, programación orientada a aspectos, es el complemento y la mejora de la POO (Programación orientada a objetos, programación orientada a objetos). ). La programación orientada a objetos introduce conceptos como encapsulación, herencia y polimorfismo para establecer una jerarquía de objetos, que se utiliza para simular una colección de comportamientos públicos. Sin embargo, la programación orientada a objetos permite a los desarrolladores definir relaciones verticales, pero no es adecuada para definir relaciones horizontales, como las funciones de registro. El código de registro a menudo se distribuye horizontalmente en todas las jerarquías de objetos y no tiene nada que ver con la funcionalidad principal del objeto al que corresponde. Esto también se aplica a otros tipos de código, como la seguridad, el manejo de excepciones y la persistencia transparente en todas partes. Se llama corte transversal en el diseño de programación orientada a objetos, lo que lleva a la duplicación de una gran cantidad de código y no favorece la reutilización de varios módulos.
La tecnología AOP es todo lo contrario. Utiliza una tecnología llamada "transversal" para diseccionar el interior del objeto encapsulado y encapsular comportamientos públicos que afectan a múltiples clases en un módulo reutilizable y llamarlo "Aspecto". , es decir, aspectos. El llamado "aspecto" simplemente significa encapsular la lógica o responsabilidades que no tienen nada que ver con el negocio pero que son llamadas por los módulos de negocio para reducir la duplicación de código en el sistema, reducir el acoplamiento entre módulos y facilitar el futuro. Operatividad y mantenibilidad.
Utilizando tecnología "transversal", AOP divide el sistema de software en dos partes: preocupaciones centrales y preocupaciones transversales. El proceso principal de procesamiento empresarial es la preocupación central, y la parte que tiene poca relación con él es la preocupación transversal. Una característica de las preocupaciones transversales es que a menudo ocurren en varios lugares de la preocupación principal, y los lugares son básicamente similares, como la autenticación de autoridad, los registros y demás. El papel de AOP es separar varias preocupaciones en el sistema, separando las preocupaciones centrales y las preocupaciones transversales.
Conceptos centrales de AOP
1. Preocupaciones transversales
¿Qué métodos deben interceptarse y cómo abordarlos después de la interceptación? Estas preocupaciones se denominan transversales. Preocupaciones cortantes.
2. Aspecto
Una clase es una abstracción de las características del objeto y un aspecto es una abstracción de preocupaciones transversales.
3. Punto de conexión ( joinpoint)
El punto interceptado, debido a que Spring solo admite puntos de conexión de tipo método, el punto de conexión en Spring se refiere al método interceptado. De hecho, el punto de conexión también puede ser un campo o estructura.
4. Pointcut
Definición de puntos de conexión de interceptación
5. Consejos
La llamada Notificación se refiere al código a ejecutar. después de interceptar el punto de conexión, las notificaciones se dividen en cinco categorías: notificaciones previas, posteriores, de excepción, finales y circundantes
6 Objeto de destino
El objeto de destino del proxy.
7. Tejido
El proceso de aplicar aspectos al objeto objetivo y dar como resultado la creación del objeto proxy
8.
Presentamos la capacidad de agregar dinámicamente algunos métodos o campos a las clases durante el tiempo de ejecución sin modificar el código
Soporte de Spring para AOP
Spring El proxy AOP es generado y administrado por el IOC de Spring contenedor, y sus dependencias también son administradas por el contenedor IOC. Por lo tanto, el proxy AOP puede utilizar directamente otras instancias de bean en el contenedor como objetivos, y esta relación puede proporcionarse mediante la inyección de dependencia del contenedor IOC.
Las reglas de Spring para crear un proxy son:
1. Utilice el proxy dinámico Java de forma predeterminada para crear un proxy AOP, de modo que pueda crear un proxy para cualquier instancia de interfaz
2. una clase necesita un proxy Cuando no se utiliza la interfaz de proxy, Spring cambiará a usar el proxy CGLIB, o puede forzar el uso de CGLIB
La programación AOP es en realidad una cuestión muy simple. Mirando la programación AOP. los programadores solo necesitan participar en tres partes:
1. Definir componentes comerciales comunes
2 Definir puntos de entrada, un punto de entrada puede cruzar múltiples componentes comerciales
3. Definir procesamiento mejorado, procesamiento mejorado Es la acción de procesamiento integrada en el marco de AOP para componentes comerciales ordinarios.
Entonces, la clave para la programación de AOP es definir el punto de entrada y el procesamiento de mejora una vez que se realiza la entrada adecuada. Se definen el procesamiento de punto y mejora, el marco AOP generará automáticamente un proxy AOP, es decir: el método del objeto proxy = mejorar el método de procesamiento del objeto proxy.
La siguiente es una plantilla de archivo Spring AOP .xml, denominada aop.xml, y el contenido posterior se expande en aop.xml:
lt;?xml version= "1.0" encoding="UTF-8"?gt;lt;beans xmlns=".xrq.aop.HelloWorldImpl1" /gt;
lt;bean id="helloWorldImpl2" class="com.xrq .aop. HelloWorldImpl2" /gt;
lt; bean id="timeHandler" class="com.xrq.aop.TimeHandler" /gt;
lt; aop: configgt;
lt; aop: aspecto id="time" ref="timeHandler"gt;
lt; aop: pointcut id="addAllMethod" expresión="ejecución(* com.xrq .aop. HolaMundo.*(..))" /gt;
lt; aop: before método="printTime" pointcut-ref="addAllMethod" /gt;
lt ;aop: después de método="printTime" pointcut-ref="addAllMethod" /gt;
lt; /aop: aspectogt;
lt; /p>
Escribe una función principal y llámala:
public static void main(String[] args)
{
ApplicationContext ctx =
new ClassPathXmlApplicationContext("aop.xml");
HelloWorld hw1 = (HelloWorld)ctx.getBean("helloWorldImpl1");
HelloWorld hw2 = (HelloWorld )ctx.getBean("holaMundoImpl2");
hw1.printHelloWorld();
System.out.println();
hw1.doPrint () ;
System.out.println();
hw2.printHelloWorld();
System.out.println();
hw2.doPrint();
}
El resultado de la ejecución es:
CurrentTime = 1446129611993Ingrese HelloWorldImpl1.printHelloWorld()
CurrentTime = 1446129611993HoraActual = 1446129611994Ingrese HelloWorldImpl1.doPrint()
HoraActual = 1446129611994HoraActual = 144612961
1994Ingrese HelloWorldImpl2.printHelloWorld()
CurrentTime = 1446129611994CurrentTime = 1446129611994Ingrese HelloWorldImpl2.doPrint()
CurrentTime = 1446129611994
Ver las dos clases de implementación para la interfaz HelloWorld Todos Los métodos se agregan con proxies y el contenido del proxy es el tiempo de impresión.
Otros detalles sobre el uso de AOP basado en Spring
1. Agregue una preocupación transversal para imprimir registros. la clase es:
clase pública LogHandler
{ public void LogBefore()
{
System.out.println("Registrar antes método" );
}
public void LogAfter()
{
System.out.println("Registrar después del método"
}
}
lt;?xml version="1.0" encoding="UTF-8"?gt;lt;beans xmlns=" .xrq .aop.HelloWorldImpl1" /gt;
lt; bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2" /gt;
lt; bean id =" timeHandler" class="com.xrq.aop.TimeHandler" /gt;
lt; bean id="logHandler" class="com.xrq.aop.LogHandler" /gt;
lt; aop: configgt;
lt; aop: aspecto id="time" ref="timeHandler" order="1"gt; pointcut id ="addTime" expresión="execution(* com.xrq.aop.HelloWorld.*(..))" /gt;
lt;aop: antes del método="printTime" pointcut-ref =" addTime" /gt;
lt; después del método="printTime" pointcut-ref="addTime" /gt; p>
lt; aop: aspecto id="log" ref="logHandler" orden="2"gt;
lt; aop: pointcut id="printLog" expresión="ejecución(* com.xrq.aop.HelloWorld.*(..))" /gt;
lt; aop: before método="LogBefore" pointcut-ref="printLog" /gt;
lt; aop: después del método = "LogAft"
er" pointcut-ref="printLog" /gt;
lt;/aop:aspectgt;
lt;/aop:configgt;lt;/beansgt;
La clase de prueba permanece sin cambios y el resultado impreso es:
CurrentTime = 1446130273734
Registrar antes del método
Ingrese HelloWorldImpl1.printHelloWorld()
Registrar después del método
CurrentTime = 1446130273735
CurrentTime = 1446130273736
Registrar antes del método
Ingrese HelloWorldImpl1.doPrint()
Registrar después del método
CurrentTime = 1446130273736
CurrentTime = 1446130273736
Registrar antes del método
Ingrese HelloWorldImpl2. printHelloWorld()
Registrar después del método
CurrentTime = 1446130273736
CurrentTime = 1446130273737
Registrar antes del método
Ingrese HelloWorldImpl2. doPrint()
Registrar después del método
CurrentTime = 1446130273737
Hay dos formas de usar logHandler antes de timeHandler:
(1) Hay un atributo de orden en el aspecto, y el número del atributo de orden es el orden de las preocupaciones transversales.
(2) Defina logHandler delante de timeHandler de forma predeterminada. aspecto como el orden de tejido
2. Solo quiero entrelazar algunos métodos en la interfaz
Simplemente modifique la expresión de pointcut:
lt;?xml version ="1.0 " codificación="UTF-8"?gt;lt;beans xmlns=".xrq.aop.HelloWorldImpl1" /gt;
lt;bean id="helloWorldImpl2" class="com. xrq.aop .HelloWorldImpl2" /gt;
lt; bean id="timeHandler" class="com.xrq.aop.TimeHandler" /gt;
lt; bean id= "logHandler" class="com.xrq.aop.LogHandler" /gt;
lt;aop:configgt;
lt;aop:aspect id="time" ref=" timeHandler" orden ="1"gt;
lt; aop: pointcut id="addTime" expresión="ejecución(* co
m.xrq.aop.HelloWorld.print*(..))" /gt;
lt;aop: antes del método="printTime" pointcut-ref="addTime" /gt;
lt; aop: después de método="printTime" pointcut-ref="addTime" /gt;
lt; /aop: aspectogt
lt; ="log" ref="logHandler" order="2"gt;
lt; aop: pointcut id="printLog" expresión="ejecución(* com.xrq.aop.HelloWorld.do*( ..))" /gt;
lt; aop: antes del método="LogBefore" pointcut-ref="printLog" /gt;
lt; aop: después del método=" LogAfter" pointcut-ref="printLog" /gt;
lt; /aop: aspectogt;
lt; /aop: configgt; lt; /beansgt;
Indica que timeHandler solo entrelazará los métodos que comienzan con print de la interfaz HelloWorld, y logHandler solo entrelazará los métodos que comienzan con do de la interfaz HelloWorld
3. Forzar el uso de CGLIB para generar agentes <. /p>
Como se mencionó anteriormente, existen reglas para que Spring use proxies dinámicos o CGLIB para generar proxies. Las versiones superiores de Spring elegirán automáticamente si usar proxies dinámicos o CGLIB para generar contenido proxy. el uso de CGLIB para generar servidores proxy, es decir, lt; aop: configgt; hay un atributo "proxy-target-class" si el valor de este atributo se establece en verdadero, entonces el proxy basado en clases funcionará. class se establece en false o se omite este atributo, entonces el proxy basado en interfaz funcionará
.