Programmer clique (Português)

O proxy dinâmico é dividido em proxy dinâmico JDK e proxy dinâmico CGLIB. O uso comum está na mola aop.

  • proxy dinâmico JDK : O método com o mesmo nome na interface é usado para chamar o método da mesma implementação na classe proxy gerada dinamicamente; O proxy implementa a classe de interface e a classe sem a interface não pode usar o proxy dinâmico JDK. Zh
  • Dynamic CGLIB proxy: Herdar a classe executiva, a classe proxy dinâmica gerada é uma subclasse da classe executiva, que é substituída pela anexação do método de negócios; A classe final modificada não pode ser proxy. Para usar o agente CGLIB, você deve importar o pacote JAR CGLIB.

proxy dinâmico JDK

A classe proxy usada pelo proxy dinâmico JDK é realmente criada pela JVM quando O programa chama o objeto da classe proxy. O motor é executado e, em seguida, faz chamadas para os métodos através deste objeto de classe proxy.

Por que a proxy dinâmica implementa interfaces?

Quando o proxy dinâmico JDK é implementado usando invocaçãoHandler, o proxy a classe deve herdar proxy. Enquanto a classe proxy deve ser herdada para obter os métodos relevantes e os construtores de invocação, Java não pode herdar as duas classes ao mesmo tempo. Para estabelecer uma conexão com a classe proxy, apenas a implementação de interface

do proxy dinâmico JDK (a interface tem classe de implementação)

1. Criar classes e interfaces 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); }}

Crie uma classe proxy InvokeProxy e implemente a interface de invocação handhandler

/* * @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 de proxy dinâmico

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"); }}

implementação do proxy Dynamic JDK (a interface não tem classe de implementação)

1. Crie uma interface proxy

public interface SellService { String sell(String name);}

2. Crie a classe InvokeProxy Proxy e implemente a interface InvocationHandler

/* * @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 de proxy dinâmico

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")); }}

proxy dinâmico CGLIB

cglib implementa proxies para as classes. O princípio é gerar uma subclasse da classe empresarial especificada e substituir os métodos de negócios para implementar o proxy. Porque a herança é usada, não pode proxy financiar as classes modificadas. Zh

1. Adicionar dependências

 <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.4</version> </dependency>

2. Crie uma classe proxy sem implementar uma interface (também é possível implementar uma interface, ela não afeta)

/* * @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. Implemente a interface proxy do método do interceptor do método e crie uma 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 de proxy dinâmico

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"); }}

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *