Il proxy dinamico è suddiviso in Dynamic Proxy JDK e Dynamic Proxy Cglib. L’uso comune è in primavera AOP.
- Dynamic Proxy JDK : Il metodo con lo stesso nome nell’interfaccia viene utilizzato per chiamare il metodo della stessa implementazione nella classe proxy generata dinamicamente; Il proxy implementa la classe di interfaccia e la classe senza l’interfaccia non può utilizzare il proxy dinamico JDK. Zh
- dinamico cglib proxy: ereditando la classe business, la classe di proxy dinamica generata è una sottoclasse della classe business, sostituita annullando il metodo aziendale; La classe finale modificata non può essere proxy. Per utilizzare l’agente cglib, è necessario importare il pacchetto JAR CGLB.
Dynamic Proxy JDK
La classe proxy utilizzata dal dinamico proxy jdk è davvero creato da JVM quando Il programma chiama l’oggetto della classe proxy. Il motore funziona e quindi effettua chiamate ai metodi attraverso questo oggetto di classe proxy.
Perché la dinamica proxy jdk implementa le interfacce?
quando il proxy dinamico JDK viene implementato utilizzando InvocationHandler, il proxy La classe deve ereditare il proxy. Mentre la classe proxy deve essere ereditata per ottenere i metodi pertinenti e i costruttori di invocationhandler, Java non può ereditare entrambe le classi contemporaneamente. Per stabilire una connessione con la classe proxy, solo l’implementazione dell’interfaccia
del proxy dinamico JDK (l’interfaccia ha la classe di implementazione)
1. Creare classi e interfacce proxy
public interface BuyService { void buy(String name);}
import com.uv.service.BuyService;public class BuyServiceImpl implements BuyService{ @Override public void buy(String name) { System.out.println("buy " + name); }}
Creare una classe Proxy InvokeProxy e implementazione dell’interfaccia Invocationhandhier
/* * @author uv * @date 2018/10/12 13:04 * */import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class InvokeProxy implements InvocationHandler{ // El objeto real para proxy private Object subject; public InvokeProxy(Object subject) { this.subject = subject; } /** * El objeto real que el proxy @param está representando * Método @param Objeto Método para llamar a un método del objeto real * @param args Los parámetros aceptados al llamar a un método del objeto real */ @Override public Object invoke(Object proxy, Method method, Object args) throws Throwable { System.out.println("start method:" + method.getName()); method.invoke(subject, args); System.out.println("end method:" + method.getName()); return null; }}
3. Uso del proxy dinamico
import com.uv.proxy.InvokeProxy;import com.uv.service.BuyService;import com.uv.service.impl.BuyServiceImpl;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;/** * <uv> */public class Main { public static void main(String args) { // El objeto real para proxy BuyService service = new BuyServiceImpl(); InvocationHandler handler = new InvokeProxy(service); /* * El nuevo método ProxyInstance del proxy para crear nuestro objeto proxy * El primer parámetro handler.getClass (). GetClassLoader () usa el objeto ClassLoader de la clase handler para cargar nuestro objeto proxy * El segundo parámetro realSubject.getClass (). GetInterfaces (), la interfaz proporcionada para el objeto proxy es la interfaz implementada por el objeto real, lo que significa que quiero proxy del objeto real, por lo que puedo llamar a los métodos en este conjunto de interfaces Arriba * El tercer controlador de parámetros, asocia este objeto proxy con el objeto InvocationHandler anterior */ BuyService buyService = (BuyService)Proxy.newProxyInstance(handler.getClass().getClassLoader(), service.getClass().getInterfaces(), handler); buyService.buy("cap"); }}
Implementazione del proxy dinamico JDK (l’interfaccia non ha classe di implementazione)
1. Creare un’interfaccia proxy
public interface SellService { String sell(String name);}
2. Creare la classe PROXY INVOKEPROXY e implementare l’INVIOCAZIONE Interfaccia
/* * @author uv * @date 2018/10/12 13:56 * No hay proxy dinámico que implemente la interfaz de clase */import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class InterfaceProxy implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object args) throws Throwable { System.out.println ("Llamada al método de interfaz iniciada"); // método de ejecución System.out.println("method name:" + method.getName()); System.out.println("method args:" + args); System.out.println ("Fin de la llamada al método de interfaz"); return "sell " + args; } public static <T> T newInterfaceProxy(Class<T> intf) { ClassLoader classLoader = intf.getClassLoader(); Class<?> interfaces = new Class{intf}; InterfaceProxy proxy = new InterfaceProxy(); return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy); }}
3. Uso del proxy dinamico
import com.uv.proxy.InterfaceProxy;import com.uv.service.SellService;/** * <uv> */public class Main { public static void main(String args) { SellService sellService = InterfaceProxy.newInterfaceProxy(SellService.class); System.out.println(sellService.sell("cap")); }}
dinamico proxy cglib
cglib implementa i proxy per le classi. Il principio è quello di generare una sottoclasse della classe business specificata e sovrascrivere i metodi aziendali per implementare il proxy. Poiché l’ereditarietà è utilizzata, non può proxy le classi modificate finiste. ZH
1. Aggiungi dipendenze
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.4</version> </dependency>
2. Creare una classe proxy senza implementare un’interfaccia (è anche possibile implementare un’interfaccia, non influisce)
/* * @author uv * @date 2018/10/12 14:37 * Clase de proxy que no implementa ninguna interfaz */public class SayService { public void say(String name) { System.out.println("Hello " + name); }}
3. Implementare l’interfaccia proxy del metodo Metodo interceptor e creare una classe proxy
/* * @author uv * @date 2018/10/12 14:36 * */import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class CglibProxy implements MethodInterceptor{ // Objeto comercial, que se representará private Object subject; // Equivalente al enlace en proxy dinámico JDK public <T> T getInstance(T subject) { // Asigna valores a objetos comerciales this.subject = subject; // Crear potenciador, usado para crear clases de proxy dinámico Enhancer enhancer = new Enhancer(); // Especifique la clase de negocio a proxy para el potenciador (es decir, especifique la clase padre para la clase de proxy generada a continuación) enhancer.setSuperclass(this.subject.getClass()); // Establezca la devolución de llamada: se llamará a CallBack para todos los métodos en la clase proxy, y Callback debe implementar el método intercept () para bloquear enhancer.setCallback(this); // Crea un objeto de clase proxy dinámico y devuelve return (T)enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object args, MethodProxy proxy) throws Throwable { System.out.println("before"); // Llamar al método de la clase de negocios (en la clase padre) proxy.invokeSuper(obj, args); System.out.println("after"); return null; }}
4. Uso del proxy dinamico
import com.uv.proxy.CglibProxy;import com.uv.service.impl.SayService;/** * <uv> */public class Main { public static void main(String args) { // El objeto que se representa SayService sayService = new SayService(); // clase de proxy CglibProxy cglibProxy = new CglibProxy(); SayService service = cglibProxy.getInstance(sayService); service.say("Tom"); }}