Modo de diseño: (modo de agente)

Modo agencia:

         El modo proxy también es una implementación del principio de apertura y cierre. La función se extiende sin cambiar el código fuente, y el objeto de destino está encapsulado por el objeto de proxy, que oculta el objeto de destino y realiza una preventa del original. Función postventa; Spring Aop es un modelo típico de agencia

         Modo proxy estático:

   

// 目标对象和代理对象实现同一个接口
interface Interface01{
    void fun01();
}
// 目标对象
class TargetClass implements Interface01{

    @Override
    public void fun01() {
        System.out.println("执行目标对象函数");
    }
}
// 代理对象
class ProxyClass implements Interface01{
   // 目标对象
    private TargetClass targetClass ;
   // 有参构造器(传入一个目标对象的实例)
    public ProxyClass(TargetClass targetClass) {
        this.targetClass = targetClass;
    }
    // 执行方法
    @Override
    public void fun01() {
        System.out.println("执行前***");
        targetClass.fun01();
        System.out.println("执行后***");
    }
}

   Proxy dinámico:

        Dado que los agentes estáticos necesitan una clase de proxy cada vez, aparece un proxy dinámico y la clase de proxy se crea de forma dinámica

      Proxy dinámico compatible con j'd'k: el proxy dinámico de jdk se basa en interfaces y la clase de destino debe implementar una interfaz, pero de hecho no todas las clases tienen una interfaz.

public class TestDynamicProxy {
    public static void main(String[] args) {
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(new TargetDncymicClass());
        // 获取代理对象
        Interface02 proxy = (Interface02) myInvocationHandler.getProxy();
        proxy.fun02();
    }
}
// 接口
interface  Interface02{
      void fun02();
}
// 目标类
class TargetDncymicClass implements Interface02{

    @Override
    public void fun02() {
        System.out.println("TargetDncymicClass...");
    }
}
// invocationHandler
class MyInvocationHandler implements InvocationHandler{
    private Object target;
    // 传入目标对象
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("执行前。。");
        // 执行目标方法
        Object object = method.invoke(target, args);
        System.out.println("执行后。。");
        return object;
    }
    // 获取生成的代理对象
    public Object getProxy() {
        // 参数1 类加载器,参数2 目标类的所有实现接口, 参数3 InvocationHandler
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this);
    }
}

Cglib:

   El proxy dinámico implementado por cglib no requiere que la clase de destino implemente la interfaz, y la capa inferior usa código de bytes asm para generar el código de bytes de la clase de proxy.

// 定义目标类
class TargetCglibClass{
// 目标方法
    public void test() {
        System.out.println("TargetCglibClass...");
    }

// methodInterceptor 方法拦截器
class MyMethodInterceptor implements MethodInterceptor{

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("执行前。。");
        // 执行目标方法
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("执行后。。");
        return object;
    }
}

//测试
  public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(TargetCglibClass.class);
        enhancer.setCallback(new MyMethodInterceptor());
        TargetCglibClass o = (TargetCglibClass) enhancer.create();
        o.test();
    }

 

La diferencia entre la implementación de proxy dinámico jdk y cglib

1. La clase de proxy y la clase delegada generada por el proxy dinámico jdk implementan la misma interfaz;
2. El código de bytes generado en el proxy dinámico cglib es más complicado. La clase de proxy generada es una subclase de la clase delegada y no puede manejar palabras clave finales
.Método modificado: 3. jdk usa el mecanismo de reflexión para llamar al método de la clase delegada, y cglib usa el método similar al índice para llamar directamente al método de la clase delegada;

Supongo que te gusta

Origin blog.csdn.net/xiaodujava/article/details/88866292
Recomendado
Clasificación