Que es AOP
Se puede decir que AOP (programación orientada al aspecto, programación orientada a los aspectos) es un suplemento y una mejora de la OOP (programación orientada a objetos). OOP introduce conceptos como encapsulación, herencia y polimorfismo para establecer una jerarquía de objetos para simular una colección de comportamientos públicos. 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.
Introducción
El patrón de diseño Java que escribí hace algún tiempo: el patrón de poder. Recientemente, cuando estaba mirando Spring AOP, sentí que debería haber conexiones cercanas en el patrón de poder, por lo que decidí comprender el principio de implementación de Spring AOP.
Hablando de AOP, tenemos que hablar sobre OOP. Los conceptos de encapsulación, herencia y polimorfismo se introducen en OOP para establecer una jerarquía de objetos para simular una colección de comportamientos públicos. Sin embargo, si necesitamos introducir piezas comunes para algunos objetos, OOP introducirá mucho código duplicado. Por ejemplo: función de registro.
La tecnología AOP utiliza una técnica llamada "corte transversal" para diseccionar el interior del objeto encapsulado y encapsular los comportamientos comunes que afectan múltiples clases en un módulo reutilizable, lo que puede reducir la duplicación del código del sistema, reducir el acoplamiento entre módulos y facilitar la operabilidad y el mantenimiento futuros. AOP divide el sistema de software en dos partes: preocupación central y atención transversal. El principal proceso de procesamiento comercial es el enfoque central, y la parte que tiene poco que ver con él es el enfoque transversal. Una característica de las preocupaciones transversales es que a menudo ocurren en múltiples preocupaciones del núcleo, y son básicamente similares en todas partes. Por ejemplo, autenticación de permisos, registro y procesamiento de transacciones.
Principio de implementación
Cuando estaba aprendiendo el modo proxy, aprendí que el modo proxy se divide en proxy dinámico y proxy estático. Ahora primero implementaremos nuestro propio marco AOP basado en el modelo proxy y luego estudiaremos los principios de implementación de la AOP de Spring.
Primero, se implementa con un proxy estático. La clave para el proxy estático es implementar una interfaz común entre el objeto proxy y el objeto de destino, y el objeto proxy contiene una referencia al objeto de destino.
Código de interfaz pública:
interfaz pública ihello {/*** Método de negocios*@param str*/void sayhello (string str);} Código de clase de destino: clase pública Hello implementa ihello {@OverridePublic Void Sayhello (String Str) {System.out.println ("Hello"+Str);}} Para el código de clase proxy, le agregamos la función de registro y ejecutamos métodos específicos antes y después de que se inicia el método. ¿No es particularmente similar a AOP?
Public Class Proxyhello implementa ihello {privado ihello hello; Public Proxyhello (ihello hello) {super (); this.hello = hello;}@overridePublic void sayshello (string str) {logger.start (); // Agregar método específico Hello.sayhello (str); logger.end ();}} Código de clase de registro:
public class logger {public static void start () {system.out.println (new Date ()+ "Di Hello Start ...");} public static void end () {System.out.println (new Date ()+ "Say Hello End");}} Código de prueba:
Prueba de clase pública {public static void main (string [] args) {ihello hello = new ProxyHello (new Hello ()); // Si necesitamos función de registro, use la clase Proxy // ihello hello = new Hello (); // Si no necesitamos la función de registro, use la clase de destino Hello.sayhello ("mañana");; }}De esta manera, implementamos el AOP más simple, pero habrá un problema: si tenemos muchas clases como Hello, ¿deberíamos escribir muchas clases como HelloProxy? De hecho, también es algo muy problemático. Después de JDK1.3, JDK nos proporciona una API java.lang.reflect.InvocationHandler Clase. Esta clase nos permite hacer algo dinámicamente para algunos métodos cuando el JVM llama a los métodos de una determinada clase. Implementemos la implementación de proxy dinámico.
La implementación de proxy dinámico implementa principalmente InvocationHandler e inyecta el objeto de destino en el objeto proxy, utilizando el mecanismo de reflexión para ejecutar el método del objeto de destino.
La implementación de la interfaz es la misma que el proxy estático, el código de clase proxy:
public class DynaproxyHello implementa InvocationHandler {private Object Target; // Object Target/*** Instanciar el objeto de destino a través de la reflexión* @param objeto* @return*/public object bind (objeto objeto) {this.target = object; return proxy.newproxyinstance (this.target.getClass (). esto);}@overridePublic Object Invoke (Object Proxy, Method Method, Object [] args) lanza lanzable {objeto resultado = null; logger.start (); // Agregar métodos adicionales // métodos para ejecutar objetos de destino a través del mecanismo de reflexión Result = Method.inVoke (this.target, args); logger.end (); return surt;}}} Código de clase de prueba:
public class Dynatest {public static void main (string [] args) {ihello hello = (ihello) new Dynaproxyhello (). bind (new Hello ()); // Si necesitamos función de logging, use proxy class // ihello hello = new hello (); // si no necesitamos la función de registro, use la clase de tarea hello. Después de leer el código anterior, puede haber un problema en comparación con Spring AOP. La clase de registro solo se puede imprimir antes y después del método, pero AOP debe poder ejecutar cuando se cumplan las condiciones. ¿Se puede desacoplar todo el objeto Dynapoxyhello y el objeto de operación de registro (Logger)?
Mirando la siguiente implementación del código, desacoplará el objeto Dynapoxyhello y el objeto de operación de registro (Logger):
Necesitamos agregar código de operación de registro (u otro código de operación) antes o después del método del objeto proxy. Luego, podemos abstraer una interfaz, que tiene solo dos métodos: uno es el método ejecutado antes de que el objeto proxy desee ejecutar el método. Lo llamamos Inicio, y el segundo método es el método ejecutado después de que el objeto proxy ejecuta el método, y lo llamamos Fin.
Interfaz del registrador:
interfaz pública ilogger {void start (método método); void final (método método);} Implementación de la interfaz de registrador:
public class dlogger implementa ilogger {@OverridePublic void start (método método) {system.out.println (new date () + método.getName () + "diga hola start ...");}@overridePublic void end (método método) {system.out.println (new date () + método Clase de proxy dinámico:
La clase pública Dynaproxyhello implementa InvocationHandler {// Llame Object private Object proxy; // Object Target Private Object Target; Public Object Bind (Object Target, Object Proxy) {this.target = Target; this.proxy = proxy; return proxy.newproxyinstance (this.target.getClasssS (). this.target.getClass (). getInterfaces (), this);}@overRidePublic Object Invoke (Object Proxy, Method Method, Object [] args) lanza lando {objeto resultado = null; // Reflection Obtiene la clase de instancia del operador clazz = this.proxy.getClass (); // Reflection obtiene el método de inicio del operador del operador. Class [] {Method.class}); // Reflection ejecuta el método de inicio start.invoke (this.proxy, nuevo objeto [] {this.proxy.getClass ()}); // Ejecuta el método original para procesar el método de objeto.invoke (this.target, args); // refleja obtiene el método del operador del operador final = clazz.getDeclaedmethod (fins, argumenta); Class [] {Method.class}); // Reflection ejecuta el método final end.invoke (this.proxy, nuevo objeto [] {método}); return resultado;}} Código de prueba:
public class Dynatest {public static void main (string [] args) {ihello hello = (ihello) new Dynaproxyhello (). bind (new Hello (), new dlogger ()); // Si necesitamos función de registro, use la clase proxy // ihello hello = new hello (); // si no necesitamos la función de registro de registro, use la clase de la clase objetivo de la clase objetivo hola.sayhello ("mañana");}} A través del ejemplo anterior, podemos encontrar que a través de la tecnología dinámica de proxyer y transmisión, la función de AOP se ha implementado básicamente. Si solo necesitamos imprimir el registro antes de ejecutar el método, no podemos implementar el método End (), para que podamos controlar el tiempo de impresión. Si queremos que el método especificado imprima el registro, solo necesitamos agregar un juicio sobre el nombre del método al método Invoke (). El nombre del método se puede escribir en el archivo XML, para que podamos desacoplarlo con el archivo de configuración, de modo que implementemos un marco SPRING AOP simple.
El contenido anterior es el Principio de Implementación Spring AOP que le presenta el editor. ¡Espero que te sea útil!