Implementación de proxy dinámico
Modo utilizado: modo proxy.
La función del modo proxy es proporcionar un proxy para que otros objetos controlen el acceso a este objeto. Similar a una agencia de alquiler.
Dos proxy dinámico:
(1) proxy dinámico JDK. El proxy dinámico JDK se implementa mediante el mecanismo de reflexión dentro de Java. La clase de destino se basa en una interfaz unificada (InvocationHandler)
(2) Proxy dinámico CGLIB, y la capa subyacente de proxy dinámico CGLIB se implementa con la ayuda de ASM. El proxy dinámico implementado por la biblioteca de terceros, como CGLIB, se usa más ampliamente y tiene más ventajas en eficiencia.
Marco de la aplicación principal:
AOP en primavera, interceptor en Struts2
Implementación específica:
1. Definir interfaces e implementar clases
paquete com.example.service; Public Interface UserService {public String getName (int id); Public Enteger Getage (int id);} paquete com.example.service.impl; import com.example.service.userservice; public class UserServiceImpl implementa UserService {public String getName (int id) {System.out.println ("------- GetName -----"); regresar "gato"; } public Integer GetAge (int id) {System.out.println ("------ GetAge -----"); regresar 10; }}2. Implementación de proxy dinámico JDK
paquete com.example.jdk; import java.lang.reflect.invocationHandler; import java.lang.reflect.method; import java.lang.reflect.proxy; clase pública myInVocationHandler implementa InvocationHandler {objetivo de objeto privado; / ** * Binde el objeto Delegate y devuelva una clase proxy * * @param Target * @return */ public object bind (objetivo de objeto) {this.target = target; // Obtenga el retorno del objeto proxy proxy.newproxyInstance (target.getClass (). GetClassLoader (), target.getClass (). GetInterfaces (), this); // Para unir la interfaz (este es un defecto, CGLIB compensa para este defecto)} @Override Public Object Invoke (Object Proxy, Method Method, Object [] args) lanza lando {if ("getName" .equals (método.getName ())) {System.out.println ("------- antes" + Method.getName () + "-----"); Resultado del objeto = método.invoke (Target, args); System.out.println ("------ después" + método.getName () + "------"); resultado de retorno; } else {objeto resultado = método.invoke (target, args); resultado de retorno; }}} paquete com.example.jdk; import com.example.service.userservice; import com.example.service.impl.userserviceImpl;/*** Test class*/public class runjdk {public static void main (string [] String [] UserService UserServiceProxy = (UserService) proxy.bind (nuevo UserServiceImpl ()); System.out.println (UserServiceProxy.getName (1)); System.out.println (UserServiceProxy.getage (1)); }}Resultados de ejecución:
------ antes de GetName ----
------ GetName -----
------ después de GetName -----
gato
----- Getage -----
10
3. Implementación de proxy dinámico CGLIB:
El mecanismo dinámico de proxy de JDK solo puede proxies las clases que implementan interfaces, pero las clases que no pueden implementar interfaces no pueden implementar el proxy dinámico de JDK. CGLIB implementa proxy para clases. Su principio es generar una subclase para la clase de destino especificada y sobrescribir la mejora de la implementación del método. Sin embargo, debido a que se usa la herencia, la clase modificada por final no puede ser proxyada.
Clases centrales de CGLIB:
net.sf.cglib.proxy.enhancer clase de mejora principal
net.sf.cglib.proxy.methodinterceptor El método principal intercepta la clase, que es una subinterfaz de la interfaz de devolución de llamada y requiere la implementación del usuario.
net.sf.cglib.proxy.methodproxy La clase proxy de Java.lang.reflect.Method Class of JDK puede implementar fácilmente llamadas a los métodos de objeto de origen.
La interfaz net.sf.cglib.proxy.methodinterceptor es el tipo de devolución de llamada más general, y a menudo es utilizado por AOP basado en proxy para implementar llamadas de método de intercepción. Esta interfaz solo define un método
Public Object Intercept (objeto objeto, java.lang.reflect.method método,
Objeto [] args, métodos proxy) lanza luneable;
El primer parámetro es el objeto proxy, y el segundo y tercer parámetros son el método interceptado y los parámetros del método, respectivamente. El método original puede llamarse utilizando una llamada de reflexión general utilizando un objeto java.lang.reflect.method, o utilizando un objeto net.sf.cglib.proxy.methodproxy. Net.sf.cglib.proxy.methodproxy generalmente se prefiere porque es más rápido.
paquete com.example.cglib; import org.springframework.cglib.proxy.enhancer; import org.springframework.cglib.proxy.methodinterceptor; import org.springframework.cglib.poxy.methodproxy; import java.lang.reflect objetivo de objeto privado; / ** * Crear objeto proxy * * @param Target * @return */ public object getInstance (Object Target) {this.target = target; Potencador potencador = nuevo mejor (); potencer.setsuperClass (this.target.getclass ()); // Método de devolución de llamada potencador.setCallback (esto); // Crea proxy Object Return Former.create (); } @Override Public Object Intercept (Object O, Method Method, Object [] Objects, MethodProxy MethodProxy) lanza Throwable {System.out.println ("+++++++++ antes"+MethodProxy.getSuperName ()+"+" +++++ "); System.out.println (método.getName ()); Resultado del objeto = métodeProxy.Invokesuper (o, objetos); System.out.println ("++++++ después"+Methodproxy.getSuperName ()+"+++++++++"); resultado de retorno; }} paquete com.example.cglib; import com.example.service.userservice; import com.example.service.impl.userserviceImpl;/** * test cglib */public class runcgglib {public static void main (String []) {cglibproxy cglibproxy = new cglibproxy (); UserService UserService = (UserService) cglibproxy.getInstance (New UserServiceImpl ()); UserService.getName (1); UserService.getage (1); }}Resultados de ejecución:
++++++ antes de cglib $ getName $ 0 +++++++++
nombre
------ GetName -----
++++++ después de cglib $ getName $ 0 +++++++++
+++++++ antes de cglib $ getage $ 1 +++++++++
getaje
----- Getage -----
++++++ después de cglib $ getage $ 1 +++++++++
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo sea de ayuda para el estudio o el trabajo de todos. ¡También espero apoyar a Wulin.com más!