Red de conocimiento informático - Consumibles informáticos - Análisis de código para programación orientada a aspectos

Análisis de código para programación orientada a aspectos

Comencemos directamente con el código. Para lograr los objetivos anteriores, podemos usar una clase de proxy dinámico (Proxy) para interceptar el comportamiento de un objeto y agregar las funciones que necesitamos. La clase java.lang.reflect.Proxy y la interfaz java.lang.reflect.InvocationHandler en Java nos proporcionan una solución para implementar clases de proxy dinámicas, pero el objeto al que se dirige esta solución debe implementar ciertas interfaces si el objetivo es una clase; cglib nos proporciona otra solución de implementación. La diferencia entre los dos se explicará más adelante. 1) Primero escriba nuestra interfaz comercial (StudentInfoService.java): public?interface?StudentInfoService{void?findInfo(String?studentName);} y su clase de implementación (StudentInfoServiceImpl.java): public?class?StudentInfoServiceImpl?implements?StudentInfoService{ public ?void?findInfo(String?name){System.out.println(El nombre que está ingresando actualmente es: nombre);}} 2) Ahora necesitamos una función de registro para ejecutar antes del comportamiento de findInfo y registrar su comportamiento, luego Simplemente intercepte este comportamiento primero. En el proceso de ejecución real, se utiliza una clase de proxy para completarlo por nosotros.

Java nos proporciona una solución para implementar clases de proxy dinámicas:

1'Clase que maneja propósitos de interceptación (MyHandler.java) import?org.apache.log4j.Logger; import?java.lang.reflect. ; import?java.lang.reflect.Proxy; import?java.lang.reflect.Method;public?class?MyHandler?implements?InvocationHandler{private?Object?proxyObj;private?static?Logger?log=Logger.getLogger( MyHandler .class); public?Object?bind(Object?obj){this.proxyObj=obj; return?Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), esto); } public?Object?invoke(Object?proxy, Method?method, Object[]?args)?throws?Throwable{Object?result=null; try{// Inserte el código aquí y llame antes del método (llame al registro Método de registro método.getName()); resultado=method.invoke(proxyObj, args);?//Método original//Inserte el código aquí, llame después del método}catch(Exception?e){e.printStackTrace() }return; ?result;}}2'Implementamos una fábrica. Para facilitarnos el uso de la clase de interceptación (AOPFactory.java): public?class?AOPFactory{private?static?Object?getClassInstance(String?clzName){Object?obj. = nulo; intente{Class?cls=Class.forName(clzName); obj=(Object)cls.newInstance();}catch(ClassNotFoundException?cnfe){System.out.println(ClassNotFoundException: cnfe.getMessage()); } catch(Exception?e){e.printStackTrace();}return?obj;}public?static?Object?getAOPProxyedObject(String?clzName){Object?proxy=null;MyHandler?handler=new?MyHandler();Object ? obj=getClassInstance(clzName); if(obj!=null)?{proxy=handler.bind(obj);}else{System.out.println(¿No se puede?obtener?el?proxyobj);//throw} return ?proxy;}} 3) Hemos implementado la interceptación básica y su fábrica, ahora prueba (ClientTest.java): pu

blic?class?ClientTest{public?static?void?main(String[]?args){StudentInfoService?studentInfo=?(StudentInfoService)AOPFactory.getAOPProxyedObject(StudentInfoServiceImpl); StudentInfo.findInfo(A Fei);}} Resultados de salida (ver); en su configuración de log4j):

Llame al método de registro de registro findInfo

El nombre que ingresa actualmente es: A Fei

De esta manera, el efecto que necesitamos Saldrá, procesamiento comercial Lo estamos haciendo nosotros mismos, pero hemos implementado la función de registro y el procesamiento comercial (StudentInfoService) no sabe que este comportamiento existe en absoluto. Sin embargo, la implementación de clases de proxy dinámicas proporcionadas en Java es para clases que implementan ciertas interfaces. Si la interfaz no está implementada, la clase de proxy no se puede crear. Consulte la parte anterior: return?Proxy.newProxyInstance(obj.getClass(). getClassLoader(), obj.getClass().getInterfaces(), esto); obj.getClass().getInterfaces() requiere la implementación de ciertas interfaces. Las siguientes son las soluciones de implementación que no implementan la interfaz: Primero, conéctese y descargue el paquete CGLib. Establecer la ruta de clase CGLib es diferente de la solución de implementación proporcionada por la biblioteca estándar de Java. cglib se implementa principalmente extendiendo una subclase basada en la clase de implementación (como StudentInfoServiceImpl.java).

Correspondiente a Proxy e InvocationHandler en Dynamic Proxy, net.sf.cglib.proxy.Enhancer y MethodInterceptor son responsables de completar la creación de objetos proxy y el procesamiento de interceptación de métodos en CGLib. Lo que se genera es una subclase de la clase de destino en lugar de implementar el método a través. Para la intercepción, Enhancer se usa principalmente para construir subclases de proxy dinámicas para implementar la intercepción, y MethodInterceptor (interfaz de devolución de llamada extendida) se usa principalmente para implementar consejos (un concepto en AOP):

1) Nuestro. procesamiento empresarial (StudentInfoServiceImpl.java): public?class?StudentInfoServiceImpl{public?void?findInfo(String?name){System.out.println (el nombre que está ingresando actualmente es: nombre);}} 2) Implemente una herramienta para procesar la función de registro (AOPInstrumenter.java): import?net.sf.cglib.proxy.MethodInterceptor; import?net.sf.cglib.proxy.Enhancer; import?net.sf.cglib.proxy.MethodProxy; lang.reflect.Método; import?org.apache.log4j.Logger;public?class?AOPInstrumenter?implements?MethodInterceptor{private?Logger?log=Logger.getLogger(AOPInstrumenter.class); (); public ?Object?getInstrumentedClass(Class?clz){enhancer.setSuperclass(clz); , Object[] ?args, MethodProxy?proxy)?throws?Throwable{(Invocar método de registro método.getName()); Object?result=proxy.invokeSuper(o, return?result;}} 3) Probemos; it (AOPTest .java): public?class?AOPTest{public?static?void?main(String[]?args){AOPInstrumenter?instrumenter=new?AOPInstrumenter(); .class) ;studentInfo.findInfo(A Fei);}}El resultado de salida es el mismo que el anterior.

Para lograr los propósitos anteriores, las clases principales proporcionadas en CGLib

1)Enhancer: setCallback(Callback), setSuperclass(Class), create() devuelve un objeto de subclase dinámica

2) La interfaz que MethodInterceptor debe implementar: intercept(Object, Method, Object[], MethodProxy) devuelve el resultado de la llamada al método original. El mismo principio que Proxy. 1) Aspecto: Implementa la función transversal y es un módulo de aspectos. El más común es el módulo de registro. De esta manera, el programa se divide en varias capas según las funciones. Si sigue la herencia tradicional, no tiene sentido que el modelo de negocio herede el módulo de registro. para lograr lo mismo creando un aspecto de registro funcional.

2) Punto de unión (punto de unión): el punto de unión es el lugar donde se inserta el aspecto en la aplicación. Este punto se puede llamar mediante métodos y también se pueden lanzar excepciones. Los puntos de unión son lugares proporcionados por la aplicación para insertar aspectos y agregar nuevos métodos. Por ejemplo, nuestro punto de corte anterior puede considerarse como el método findInfo(String).

3) Consejo (lógica de procesamiento): El consejo es la implementación de nuestra función de aspecto, que notifica al programa sobre nuevos comportamientos. Al igual que en el registro, los consejos de registro incluyen código de implementación de registro, como escribir registros en un archivo. Los consejos se insertan en la aplicación en los puntos de unión. Arriba hemos implementado la función de consejo en MyHandler.java

4) pointcut (corte de punto): pointcut puede controlar qué consejos se aplican a los puntos de unión. Por lo general, se utilizan puntos de corte para separar puntos obvios mediante expresiones regulares. Se aplica la coincidencia de patrones. Se decide qué punto conjunto será notificado.

5) Introducción: Permite agregar nuevos métodos y atributos a la clase.

6) target (clase objetivo): se refiere a aquellas clases que utilizarán asesoramiento, refiriéndose generalmente a modelos de negocio independientes. Por ejemplo, el StudentInfoServiceImpl.

7) proxy (clase de proxy) anterior: utiliza el modo proxy. Se refiere al objeto al que se aplica el consejo y se parece mucho al objeto objetivo.

8) Weaving (inserción): se refiere al proceso de aplicar aspectos a un objeto de destino para crear un objeto proxy: tiempo de cumplimiento, tiempo de carga de clase, tiempo de ejecución