Modo de agencia (estructurado)

Modo proxy

Proxy es un patrón de diseño que proporciona una forma de acceder al objeto de destino indirectamente, es decir, acceder al objeto de destino a través del objeto de proxy. La ventaja de esto es que puede agregar funciones adicionales a las funciones implementadas por el objeto de destino. Es extender la función del objeto objetivo.

Esto está en línea con el principio de abrir y cerrar el patrón de diseño, es decir, expandir la función sin cambiar el código existente.

Tome un ejemplo para ilustrar el papel del agente: la relación entre la estrella y el agente es la relación entre el agente y el agente. Cuando la estrella aparece en el evento, la estrella es un objeto objetivo. A su agente (corredor)

Para resolver, este es un ejemplo de agencia que piensa en la realidad.

Proxy estático

Cuando se utiliza un proxy estático, el objeto proxy y el objeto proxy necesitan implementar la misma interfaz o heredar la misma clase principal, por lo que debe definir una interfaz o clase abstracta.

Caso de código:

El primer paso es crear una interfaz común entre la clase proxy estática y la clase proxy

package proxy.calm;

//接口
public interface IStar {
        void sing();
}

El segundo paso es crear una clase real.

package proxy.calm;

//真实对象
class LDHStar implements IStar {
    @Override
    public void sing() {
        System.out.println("刘德华唱歌");
    }
}

El tercer paso es crear una clase proxy (necesita tener control del objeto real (referencia))

package proxy.calm;

// 静态代理类需要有真实对象的控制权 (引用)
class ProxyManger implements IStar {

    // 真实对象的引用
    private IStar star;

    public ProxyManger() {
        super();
    }

    public ProxyManger(IStar star) {
        super();
        this.star = star;
    }

    @Override
    public void sing() {
     System.out.println("唱歌前准备");
     star.sing();
     System.out.println("善后工作");
    }
}

El cuarto paso, la prueba del cliente

package proxy.calm;

public class Client {
    public static void main(String[] args) {
        // 创建明星对象
        IStar ldh = new LDHStar();
        //创建他的理
        ProxyManger proxy = new ProxyManger(ldh);
        proxy.sing();
    }
}
唱歌前准备
刘德华唱歌
善后工作

Resumen de proxy estático:
ventajas: puede expandir la función de destino sin modificar la función del objeto de destino.
Desventajas:   debido a que el objeto de proxy necesita implementar la misma interfaz que el objeto de destino, habrá muchas clases de proxy, demasiadas clases. Al mismo tiempo Una vez que la interfaz agrega métodos, se deben mantener tanto el objeto de destino como el objeto proxy.

El método proxy dinámico puede resolver el problema anterior

 

Proxy dinámico

La característica principal del proxy dinámico es que la JVM puede generar objetos proxy para los objetos proxy mientras se ejecuta el programa.

El proxy dinámico que a menudo se llama proxy JDK también es un proxy de interfaz. La clase proxy que genera el objeto proxy en JDK es Proxy. El paquete es java.lang.reflect
o el ejemplo de la estrella anterior. La interfaz y la clase proxy no cambian. Una clase de controlador para implementar la interfaz InvocationHandler.

Pasos específicos del proxy dinámico:

  1. Cree su propio manejador de llamadas implementando la interfaz InvocationHandler;
  2. Cree una clase de proxy dinámico especificando un objeto ClassLoader y un conjunto de interfaces para la clase Proxy;
  3. El constructor de la clase de proxy dinámico se obtiene a través del mecanismo de reflexión, y su único tipo de parámetro es el tipo de llamada a la interfaz del procesador;
  4. Cree una instancia de clase de proxy dinámico a través del constructor y llame al objeto procesador como parámetro durante la construcción.
package proxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

class MyInvocationHandle implements InvocationHandler {
    private Object target;
    public void setTarget(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("唱歌前准备");
            method.invoke(target, args);
            System.out.println("善后工作");
            return null;
    }
}

Cree una clase proxy y devuelva una instancia proxy de una interfaz a través del método estático newProxyInstance de la clase Proxy. Para diferentes clases de proxy, pase el controlador proxy correspondiente InvocationHandler.

package proxy.dynamic;

import java.lang.reflect.Proxy;

class MyProxyFactory{
    public static Object getProxy(Object target) {
        MyInvocationHandle handle = new MyInvocationHandle();
        handle.setTarget(target);
        Object proxy = Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                handle);
        return proxy;
    }
 }

Prueba del cliente: completó la misma función que el proxy estático

package proxy.dynamic;

public class Client {
    public static void main(String[] args) {
        IStar dog = new LDHStar();
        IStar proxy =(IStar) MyProxyFactory.getProxy(dog);
        proxy.sing();
    }
}
唱歌前准备
刘德华唱歌
善后工作

Resumen: el objeto proxy no necesita implementar la interfaz, pero el objeto de destino debe implementar la interfaz, de lo contrario no se puede usar el proxy dinámico, por lo que esto también es un defecto de este método.

 

Proxy Cglib

El proxy estático anterior y los patrones de proxy dinámico tienen el mismo punto en que requieren que el objeto de destino sea un objeto que implemente una interfaz, pero ningún objeto implementará una interfaz, y hay objetos que no implementan ninguna interfaz

En este momento, puede usar la clase de destino heredada para implementar el proxy en forma de una subclase del objeto de destino. Este método se denomina: proxy de Cglib, también conocido como proxy de subclase. Extensión.

Existe una limitación del uso del proxy dinámico JDK, es decir, el objeto que se representa debe implementar una o más interfaces. Si desea proxy de la clase que no implementa la interfaz, debe usar Cglib.

Necesito importar el paquete jar

 Ahora los objetos reales no pueden implementar ninguna interfaz

package proxy.cglib;


//真实对象
class LDHStar {
    public void sing() {
        System.out.println("刘德华唱歌");
    }
}

El segundo paso es crear la fábrica de proxy cglib

package proxy.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Cglib代理类工厂
 */
public class ProxyFactory implements MethodInterceptor {
    //维护目标对象
    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    //给目标对象创建一个代理对象
    public Object getProxyInstance(){
        //1.工具类
        Enhancer en = new Enhancer();
        //2.设置父类
        en.setSuperclass(target.getClass());
        //3.设置回调函数
        en.setCallback(this);
        //4.创建子类(代理对象)
        return en.create();

    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("唱歌前准备");
        //执行目标对象的方法
        Object returnValue = method.invoke(target, objects);
        System.out.println("善后工作");
        return returnValue;
    }
}

Comenzó la prueba y también completó la misma función.

package proxy.cglib;


public class Client {
    public static void main(String[] args) {
        // 创建明星对象
        LDHStar ldh = new LDHStar();
        //创建他的代理
        LDHStar proxy = (LDHStar) new ProxyFactory(ldh).getProxyInstance();
        proxy.sing();
    }
}
唱歌前准备
刘德华唱歌
善后工作

Adjunto:

En la programación AOP de Spring:

Si el objeto de destino agregado al contenedor tiene una interfaz de implementación, use el proxy JDK

Si el objeto de destino no implementa la interfaz, use el proxy Cglib.

138 artículos originales publicados · elogiados 34 · 150,000 visitas

Supongo que te gusta

Origin blog.csdn.net/bbj12345678/article/details/105389486
Recomendado
Clasificación