¡Un artículo es suficiente para aprender el modelo de agente de Java!

Que es un proxy dinámico

El proxy dinámico es mejorar el método sin modificar el código fuente.

El proxy estático requiere que los desarrolladores escriban clases de proxy manualmente para lograr mejoras en las clases de destino

Durante la ejecución del programa, la máquina virtual JVM crea dinámicamente un objeto proxy, podemos controlar el objeto proxy y mejorar sus métodos.

Principio de agente dinámico

  • El proxy dinámico requiere la clase de proxy y la clase de destino para implementar la misma interfaz
  • Proxy dinámico basado en la reflexión

El paso más conmovedor en la agencia dinámica

A través del objeto proxy, se llama al método del objeto de destino basándose en la reflexión.

método.invocar (xiaoWang, args);

Composición de agente dinámico

Objeto proxy

objetivo

Realización de proxy dinámico

  • Tecnología de realización de agente dinámico

      1. jdk 2. cglib
  • Pasos de implementación del proxy dinámico

    • Crear interfaz
    • Crear clase objetivo y objeto objetivo
    • Crear objeto de proxy, sin clase de proxy
    • Llame al método del objeto proxy, el proxy tiene éxito
  • Implementación de proxy dinámico

    • Introducción a la herramienta proxy

      Objeto estático newProxyInstance (cargador ClassLoader, interfaces Class <?> [], InvocationHandler h);

      Tres parámetros

      El primer cargador de parámetros El cargador de la clase de destino (objeto)

      XiaoWang.getClass (). GetClassLoader ()

      El segundo parámetro interconecta la matriz de interfaz de la clase de destino (objeto)

      XiaoWang.getClass (). GetInterfaces ()

      El tercer parámetro h: interfaz del procesador, en este parámetro, se mejora el método de destino.

      Dos métodos

      Uno: clase interna anónima

      2: expresión lambda

      El agente dinámico solo se mejora mediante métodos.

      Al implementar el tercer parámetro, debe volver a escribir el método de invocación y mejorar el método de destino en el método de invocación

      Invocación de objeto (proxy de objeto, método de método, argumentos de objeto [])

      El primer parámetro es el objeto proxy producido por la clase de herramienta proxy, xiaozhe

      El segundo método de parámetro es el objeto del método actualmente ejecutado, basado en la reflexión

      El tercer parámetro args La matriz de parámetros del método de ejecución actual

@Test
public void versi() throws Exception {
    
    
    // 1.创建目标对象
    XiaoWang xiaoWang = new XiaoWang();
    // 2.通过Proxy工具类生产代理类和创建代理对象
    DancerInterface xiaozhe = (DancerInterface) Proxy.newProxyInstance(xiaoWang.getClass().getClassLoader(), xiaoWang.getClass().getInterfaces(), new InvocationHandler() {
    
    
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
            // 当前执行的方法名
            // System.out.println(method.getName());
            // 当前执行方法的参数
            // System.out.println(Arrays.toString(args));
            // 前置增强
            if ("dance".equals(method.getName())) {
    
    
                System.out.println("小哲去工作了");
            }
            // 由代理对象调用目标对象方法
            // method的意思是方法,它是方法对象
            Object result = method.invoke(xiaoWang, args);
 			
            // 后置增强
            if ("dance".equals(method.getName())) {
    
    
                result = "小王回到了家里," + result;
            }
            // 代理对象将结果返回给调用者
            return result;
        }
    });
    // 3.调用方法
    // 目标对象方法,不进行加强,简简单单的就相当于xiaoWang执行了这个方法.
    // String result = xiaoWang.dance("香泽菠菜");
    // 代理对象方法,已增强.
    String result = xiaozhe.dance("香泽菠菜");
    // 看看代理和不代理的区别
    System.out.println(result);
}

Al final, debe ser el método de ejecución del objeto proxy. A través del mecanismo de reflexión, el método interno del método de mejora del objeto proxy sigue siendo el método original del objeto objetivo para ejecutar el objeto objetivo. La función mejorada se mejora en la invocación.

Cuando el objeto proxy llama a un método, hay tres pasos internos

1. Realice funciones mejoradas.

2. El objeto de destino ejecuta el método del objeto de destino.

2. Realizar funciones mejoradas, es decir, mejoradas previamente o mejoradas posteriormente.

package com.qinghong.test;

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

public class verwu {
    
    

    public static void main(String[] args) {
    
    

	 //	不使用代理增强
     //	Dancer dancer = new Xiaoqiang();
     //	dancer.dance();

        
     //  静态代理,Xiaozhe是自定义代理类,静态代理,两份代码同时写。
     //  Dancer dancer = new Xiaozhe();
     //  dancer.dance();

    
    //动态代理,动态的创建代理对象,不需要写实体代理类。
       // 创建目标对象
        Dancer dancer = new Xiaoqiang();
       /* 创建代理对象时要注意:
        	1、方法中传的三个参数,代理对象要跟目标对象在类加载器上和接口数组上保持一致,所以传的类加载器和接口数组都是目标对象的。
            2、类加载器,通过类加载器表明代理对象由哪个类加载器加载,要选用跟目标对象一样的类加载器,目标对象的类加载器,别装成猪了,你要装人。
            3、接口数组,通过跟目标对象一模一样的接口数组,你要装别人,你起码得知道别人长啥样,有啥衣服(方法)吧。
            4、处理器接口,增强的业务逻辑。*/
        Dancer xiaozhe = (Dancer)Proxy.newProxyInstance(dancer.getClass().getClassLoader(), dancer.getClass().getInterfaces(), new InvocationHandler() {
    
    
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
                //代理对象中,如何调用目标对象的方法。
                //你们猜,这个method是个啥玩意。
                System.out.println("你去卖烧烤吧");
                //这个方法,包含很多东西啊。
                Object obj = method.invoke(dancer, args);
                System.out.println("我不去");
                
                //方法对象有方法名,代理对象和目标对象是一个方法。
                //本质为让目标对象在这里调用它目标对象的方法.(重点!!!)
                //为什么代理对象执行这个方法就会发生反射?
                /*因为代理对象的这个方法就是在创建代理对象的过程中编写的
                执行这个方法时,自然要跑到上边创建代理对象的invoke方法中
                代理对象内部有一个大大的空间,这个空间里边有目标对象执行它目标对象方法的语句.
                代理对象类内部,动态代理没有物理上的代理类,需要虚拟代理类和目标类实现同一接口,创建代理对象时参数中前两个参数都是反射的基本条件。*/
                return obj;
            }
        });
        //代理对象调用方法
        xiaozhe.dance();
    }
}

Comprensión simple del modo proxy

El objeto proxy es envolver el objeto proxy en una capa y hacer un trabajo adicional dentro de él. Por ejemplo, el usuario necesita ir a Facebook, pero la red normal no puede acceder directamente a él. El proxy de red ayuda al usuario a cruzar el muro primero y luego visitar Facebook. Este es el papel del agente.

Proxy remoto: No podemos acceder a Facebook debido a GFW en China. Podemos usar el método de superar el muro (configuración de proxy) para acceder. El proceso de acceso es:
(1) El usuario envía una solicitud HTTP al agente.
(2) El proxy envía la solicitud HTTP al servidor web.
(3) El servidor web envía la respuesta HTTP al proxy.
(4) El proxy envía la respuesta HTTP al usuario.

La diferencia entre estático y dinámico

Proxy estático

El programador crea la clase de proxy o una herramienta específica genera automáticamente el código fuente y luego lo compila El archivo .class de la clase de proxy existe antes de que se ejecute el programa.

Ventajas: El proxy hace que el cliente no necesite saber cuál es la clase de implementación específica, cómo hacerlo, solo necesita conocer el proxy (desacoplamiento)

Desventajas:

La clase de destino implementa este método, y la clase de proxy también debe implementar este método, y el código se repite.

Si la interfaz agrega un método, todas las clases de implementación deben reescribir este método (esta interfaz no se puede personalizar para una clase de implementación para un método, debe tener varias clases de implementación), y todas las clases de proxy también deben reescribirse así El método aumenta la complejidad del mantenimiento del código.

2. El objeto proxy solo sirve para un tipo de objeto. Si desea servir varios tipos de objetos, es probable que sea un proxy para cada tipo de objeto. El proxy estático no será competente cuando la escala del programa sea un poco mayor. Si lo desea Si otras clases proporcionan proxies, necesitamos agregar otras clases de proxy nuevamente.

Es decir, la clase de proxy estático solo puede servir a una interfaz específica (Servicio). Si desea servir varias interfaces, debe crear muchas clases de proxy. Si desea usar una clase de proxy para completar todas las funciones de proxy, debe usar un proxy dinámico.

Proxy dinámico

Se crea dinámicamente mediante el mecanismo de reflexión cuando el programa se está ejecutando. Cuando el programa se está ejecutando, el mecanismo de reflexión se utiliza para realizar un proxy dinámico y puede representar varios tipos de objetos. En el programa JAVA seguimos el principio OCP (abierto para extensión, cerrado para modificación) (principio abierto y cerrado), y es la práctica del pensamiento AOP.

ventaja:

En comparación con el proxy estático, la mayor ventaja del proxy dinámico es que todos los métodos declarados en la interfaz se transfieren a un método centralizado del controlador de invocación (InvocationHandler.invoke). De esta manera, cuando el número de métodos de interfaz es relativamente grande, podemos Procesamiento flexible, sin la necesidad de transferir todos los métodos como un proxy estático, y la aplicación de proxy dinámico hace que nuestras responsabilidades de clase sean más simples y reutilizables.

La diferencia entre proxy dinámico y proxy estático

Uso: el proxy estático necesita escribir la clase de proxy manualmente

Funcionalmente: proxy estático de un tipo, proxy dinámico de varios tipos

La diferencia comercial real entre agente dinámico y agente estático

Da un pequeño ejemplo

Proxy estático, cada método en esta interfaz implementado por la clase de proxy necesita agregar código de registro

Para los agentes dinámicos, solo necesita agregar código de registro al método invoke () para agregar registro a cada método.

·············································· ·····························

¿Perdiste la escuela?

Supongo que te gusta

Origin blog.csdn.net/numbbe/article/details/109271061
Recomendado
Clasificación