JDK proxy dinámico utiliza la reflexión para generar

Proporciona un Proxy y una clase en el Java interfaces de paquete java.lang.reflect InvocationHandler se pueden generar de forma dinámica o JDK clase dinámica de proxy mediante el uso de esta clases de objetos proxy y interfaces.

Crear un proxy dinámico para utilizar proxy y InvocationHandler

Proxy proporciona métodos estáticos para crear clase de proxy dinámico y objetos proxy, también es el padre de toda la generación dinámica de clase. Si una o más clases de implementación de interfaz de programa generado dinámicamente, se puede utilizar para crear clase de proxy dinámico Proxy; si se desea para crear una instancia de una o más interfaces de forma dinámica, se pueden utilizar para crear una dinámica Proxy instancia de agente.

Proxy proporciona los dos métodos siguientes para crear un clases de proxy dinámicas y ejemplo proxy dinámico.

  • Clase getProxyClass estática (cargador de cargador de clases, interfaces de clase ... <?>) <?>: Crear un objeto de la clase dinámica de clases de proxy correspondiente a las interfaces de clase proxy sería implementar múltiples interfaces especificadas. El primer argumento especifica el cargador de clases cargador de clases para generar la clase proxy dinámico.
  • Objeto estático newProxyInstance (loader ClassLoader, interfaces de clase [], InvocationHandler h <?>): Crear directamente un objeto dinámico proxy, los implementos interfaces de clase implementación del objeto proxy especificado interfaz en serie, cada método será ejecutado objeto proxy Alternativamente InvocationHandler invoke realiza método de objeto.

De hecho, incluso después de usar el primer método para generar la clase proxy dinámico, si las necesidades del programa para crear objetos a través de la clase de proxy, todavía tienen que pasar un objeto InvocationHandler. Es decir, cada objeto proxy generada por el sistema tiene una objetos InvocationHandler asociados.

Consejo: El equipo es "estúpida", el modo de reflexión cuando el programa se utiliza para generar el objeto de interfaz de proxy especificado rango dinámico, para lograr estos implementa la clase dinámica de proxy objeto una o más interfaces, las necesidades de objetos dinámicos proxy para implementar uno o más de todos los métodos definidos en la interfaz, pero la pregunta es: ¿cómo el sistema sabe cómo poner en práctica estos métodos? Esta vez el turno InvocationHandler objetos de debut - cuando se realiza un objeto proxy dinámico en el método, de hecho, será reemplazado método invoke llamadas InvocationHandler derecha.

procedimientos de RM se pueden emplear como una clase de proxy dinámico, y luego para crear un objeto proxy por manera clase de proxy dinámico para generar un objeto dinámico proxy. El siguiente fragmento de código:

// objetos Crear un InvocationHandler 
InvocationHandler Handler = nueva nueva MyInvocationHandler (...);
 // Uso de Proxy generar una clase dinámica de proxy proxyClass 
Clase proxyClass = Proxy.getProxyClass (Foo. Clase .getClassLoader (), nueva nueva Clase [] {Foo. Clase });
 // Obtener parámetro constructor de la clase proxyC1ass con un InvocationHandler 
el constructor ctor = proxyClass.getConstructor ( nueva nueva clase [] {InvocationHandler. clase });
 // el método newInstance llamada para crear instancias dinámicas ctor 
Foo f = (Foo ) ctor.newInstance ( nuevo nuevo Object [] {} Handler);

El código anterior se puede simplificar al siguiente código:

// crear objetos de un InvocationHandler 
InvocationHandler Handler = nuevo nuevo MyInvokationHandler (...);
 // especificado para generar directamente una dinámica Proxy objeto proxy 
Foo F = (Foo) la Proxy.newProxyInstance (Foo. Clase .getClassLoader (), nueva nueva clase [ ] {. Foo clase }, Handler);

El siguiente procedimiento demuestra el uso de Proxy y InvocationHandler para generar objeto proxy dinámico.

interconectar la Persona {
     void Walk (); 

    void (nombre String) sayHello; 
} 

clase MyInvokationHandler los implementos de InvocationHandler {
     / * 
     * todos los métodos de realizar objeto proxy dinámico, serán reemplazados para realizar el método de invocación en la que: Proxy: objetos proxy dinámicos representativos método: el método se realiza en nombre de 
     args *: nombre de una llamada entrante cuando los argumentos del método objetivo. 
     * / 
    Public Object Invoke (objeto proxy, Método, Método, Object [] args) { 
        System.out.println ( "---- siendo realizada método:" + Método);
         IF (Args =! Nulo ) { 
            el System.out .println ( "a continuación se pasa a la hora de aplicar el método como argumentos:" );
             para (objeto Val: args) {
                System.out.println (Val); 
            } 
        } else { 
            System.out.println ( "llamar al método no toma ningún argumento!" ); 
        } 
        Volver  nula ; 
    } 
} 

pública  clase proxytest {
     pública  estática  vacío main (String [] args) lanza excepción {
         // crear objetos un InvocationHandler 
        InvocationHandler Handler = nuevo nuevo MyInvokationHandler ();
         // especificado InvocationHandler para generar un objeto dinámico de proxy 
        . la persona P = (la persona) la Proxy.newProxyInstance (la persona clase.getClassLoader (), nueva nueva Clase [] {la persona. clase }, 
                Handler); 
        // llamada al objeto proxy rampa móvil () y sayHello () método 
        p.walk (); 
        p.sayHello ( "mono" ); 
    } 
}

Necesita ser reescrita método invoke () anterior cuando el programa se proporciona por primera vez una interfaz persona, que contiene el paseo () y dos sayHello método abstracto (), a continuación, una simple definición de clase de implementación InvocationHandler, que define la clase de implementación - llamar a todos los métodos objeto proxy se sustituyen por el método de llamada invoke (). El método invoke () de los tres parámetros se explica a continuación.

  • Proxy: dinámico representa el objeto proxy.
  • Método: Método representa ser ejecutado.
  • args: una llamada entrante cuando el método de destino en nombre de argumentos.

La primera línea en el código negrita InvocationHandler procedimiento anterior, crea un objeto, la segunda línea de código crea un objeto dinámico de proxy negrita acuerdo objeto InvocationHandler. Ejecutar los procedimientos anteriores, ver el efecto siguiente operación como se muestra en la figura.

---- ser implementado método: pública  abstracta  vacío com.jwen.chapter18_5.Person.walk () 
Este método es llamado sin argumentos! 
---- método está implementando: pública  abstracta  vacío com.jwen.chapter18_5.Person.sayHello (java.lang.String) 
aprobada en cuando el método es para realizar el siguiente argumento es: 
Rey Mono

Como puede verse en el gráfico, independientemente del programa es caminar a la aplicación del método objeto proxy (), o la puesta en práctica del método sayHello () objeto proxy, en realidad está ejecutado método invoke objeto InvocationHandler ().

Después de leer lo anterior programa de ejemplo, los lectores pueden sentir que este programa no es mucho valor práctico, es difícil de entender Java encanto dinámico proxy. De hecho, en la programación general, de hecho, sin el uso de proxies dinámicos, pero en la preparación del marco o código subyacente, papel proxy dinámico es muy grande.

proxy dinámico y AOP

Según Proxy y InvocationHandler describen anteriormente, es difícil ver las ventajas de esta dinámica proxies. Aquí hay un mecanismo más práctico dinámico proxy.

El desarrollo de la aplicación práctica de los sistemas de software, a menudo hay casos el mismo segmento de código recurrente, en este caso, para muchas personas el comienzo participan en el desarrollo de software, y su enfoque es: seleccionar aquellos códigos, todo el camino a la "copia" "pegar", inmediatamente se dio cuenta de la función del sistema, aunque sólo sea desde el punto de vista de la funcionalidad del software, ellos han completado el desarrollo de software.

Por ejemplo una "copia" desarrollado "pegar" software del modo como se muestra a continuación.

Como se muestra en el uso de la arquitectura de software implementado en un mapa, durante el desarrollo de software puede sentir no importa, pero si no es lograr un gran código oscura necesaria para modificar el programa, que significa tres modificaciones en el código de fuente abierta. Si hay un lugar donde hasta 1000 utilizando este fragmento de código oscura, entonces la modificación, mantenimiento de la carga de trabajo de código se convertirá en una pesadilla.

En este caso, la mayoría con los desarrolladores con experiencia será oscuro este segmento de código se define como un método, y luego dejar que los otros tres secciones de fragmentos de código que se pueden llamar directamente. De esta manera, la estructura del sistema de software como se muestra en la figura.

 

Para el sistema de software se muestra arriba, si resulta necesario modificar el código parte oscura, tan largo como un lugar donde se puede modificar el segmento de código del método se invoca, no importa cuántas realiza una llamada a este método, son completamente sin ninguna modificación, mientras se modifica el método de llamada, todas las llamadas locales, naturalmente, cambiar el método - de esta manera reduce en gran medida la complejidad de la última parte del mantenimiento del software.

Pero esta manera de lograr la reutilización de código sigue generando una importante pregunta: ¿segmento de código 1, segmentos de código 2, 3 y oscuro fragmento de puntos de segmento de código de distancia, pero el segmento de código 1, fragmentos de código y código de los segmentos 2 y 3 y un determinado parejas método! Los mejores resultados son: una porción oscura bloque de código, bloque de código 2 y 3. El método se puede realizar de código, pero sin codificado en el programa para llamar directamente al bloque de código oscura, entonces puede ser proxies dinámicos para lograr este efecto.

Desde JDK proxy dinámico sólo puede crear un proxy dinámico para la interfaz, por lo que el siguiente le proporciona una interfaz de perro que el código es muy sencillo, basta con definir dos métodos de esta interfaz.

pública  interfaz de perro {
     // información método de declaración 
    nula información (); 

    // método run declaración 
    vacío run (); 
}

Por encima de la interfaz fue simplemente define dos métodos, que no proporciona un método de lograr. Si el uso directo interfaz de proxy para crear un objeto proxy dinámico para la aplicación dinámica de objeto proxy de los resultados de todos los métodos a su vez exactamente el mismo. Es a menudo el caso, el software de interfaz proporciona una o más clases de implementación para el perro, para proporcionar una clase de implementación simple aquí: perro de caza.

público  de clase GUNDOG los implementos perro {
     // implementar el método info (), solo una cadena de impresión 
    pública  nula información () { 
        System.out.println ( "Soy un perro de caza" ); 
    } 

    // método implemento run (), sólo se imprimir una cadena 
    pública  vacío run () { 
        System.out.println ( "corro rápido" ); 
    } 
}

El código especial anterior no es la menor, la clase de implementación perro sólo proporciona una implementación simple para cada método. Mirada a la necesidad de implementar la función de: hacer que el segmento de código 1, segmentos de código 2 y 3 o bien puede ejecutar segmentos de código porción oscura de código, y sin codificación de código oscuro invocación de método duro directamente en el programa. Aquí es información asumida (), método run () representa dos segmento de código 1, el segmento 2, a continuación, requisitos: método info (), run () de la realización de un programa puede llamar a un procedimiento general, pero no quieren duro codificadas este método se llama. A continuación se proporciona una clase DogUtil que contiene dos métodos generales.

público  de clase DogUtil {
     // método primera interceptor 
    pública  sin efecto la metodo1 () { 
        System.out.println ( "Simulación de un método general ===== =====" ); 
    } 

    // segundo método interceptor 
    pública  vacío metodo2 () { 
        System.out.println ( "general método II ===== ===== analógico" ); 
    } 
}

Y por medio de Proxy InvocationHandler puede lograrse - cuando el programa llama al método info () y el método run (), el sistema puede "automáticamente" a la metodo1 () y el método metodo2 () para insertar () método de dos informaciones generales () y correr en ejecución.

La clave de este procedimiento es que la siguiente clase de MyInvocationHandler, que es una clase de implementación InvocationHandler, el método de la clase de implementación Invoke () será implementado como un objeto proxy.

público  de clase MyInvokationHandler los implementos de InvocationHandler {
     // necesita ser objeto proxy 
    privado objetivo objeto; 

    pública  vacío setTarget (objetivo Object) {
         el presente .target = objetivo; 
    } 

    // la ejecución de todos los objetos proxy dinámico, serán reemplazados para realizar lo siguiente invoke método 
    público invoke objeto (Object Proxy, método, método, Object [] args) lanza la excepción { 
        DogUtil du = nuevo nuevo DogUtil ();
         // realizar DogUtil objeto method1. 
        du.method1 ();
         // En la realización del método de programación como método de destino 
        resultado Object =Method.invoke (objetivo, args);
         // realizar DogUtil objeto method2. 
        du.method2 ();
         retorno Resultado; 
    } 
}

Los anteriores implementa un programa método invoke () que comprenden una fila cuando el código de la llave (indicado en negrita), esta línea de código de objetivo tal como se refleja por el método de programación realizar el método, que es el método de devolución de llamada original del objeto de destino. DogUtil objeto antes de llamar a los códigos en negrilla el objeto DogUtil metodo1 () llamada al método después del método () Código metodo2 negrita.

A continuación se proporciona una clase adicional de programa MyProxyFactory diseñado para generar la instancia de proxy objeto dinámico para el destino especificado.

público  clase MyProxyFactory {
     // objetivo de generar objeto proxy dinámico para el especificado 
    público  estático de objetos El getProxy (objetivo Object) lanza la excepción {
         // crear objetos un MyInvokationHandler 
        MyInvokationHandler Handler = nuevo nuevo MyInvokationHandler ();
         // establecer el objeto de destino MyInvokationHandler 
        handler.setTarget (objetivo );
         // crear y devolver una dinámica de proxy 
        retorno Proxy.newProxyInstance (target.getClass () getClassLoader (), target.getClass () (getInterfaces), Handler); .. 
    } 
}

La clase de fábrica de proxy anteriormente dinámico proporciona un método El getProxy (), que genera un objeto dinámico proxy para el objeto de destino, los implementos de proxy objeto dinámico objetivo entonces importa la misma, y ​​por lo tanto tienen los mismos métodos públicos - en este sentido mirada, objeto proxy dinámico se puede utilizar como objetos de destino a su utilización. Cuando el programa llama al método especificado del objeto proxy dinámico, de hecho, se convierte en método invoke () para realizar MyInvocationHandler objeto. Por ejemplo, una llamada al método info objeto dinámico proxy (), la ejecución invocar el método (), que realiza los siguientes pasos.

  1. La creación de instancia DogUtil.
  2. method1 realizó método DogUtil ejemplo ().
  3. Un blanco reflectante para llevar a cabo el método como información de llamadas ().
  4. Ejemplos método de ejecución DogUtil method2 () de.

Tanto durante la información de ejecución del programa (), método run () "Insertar - Cuando se utiliza objeto proxy dinámico en lugar del objeto de destino, a un apoderado métodos de objeto para alcanzar los requisitos previos: ver la puesta en práctica del proceso anterior, el lector debería haber sido encontrado "method1 (), method2 () método general, pero el gundog método en y no hay llamadas method1 no modificable () y method2) método (.

Aquí hay un programa principal para probar el efecto de este proxy dinámico.

público  de clase Test {
     públicas  estáticas  void main (String [] args) lanza la excepción {
         // crear un objeto original como perro de caza de destino 
        objetivo Perro = nuevo nuevo perro de caza ();
         // destino especificado para crear un proxy dinámico 
        del perro = ( Dog) MyProxyFactory.getProxy (objetivo); 
        dog.info (); 
        dog.run (); 
    } 
}

perro objetos programa anterior es en realidad un objeto dinámico proxy, pero el objeto proxy dinámico también implementa la interfaz de perro, por lo que también se puede utilizar como un objeto perro. método cuando la información perro ejecución del programa () y run (), de hecho, primero se ejecutará el método de metodo1 DogUtil (), y luego realizar la información objeto de destino () y el método run (), la implementación final del método () metodo2 DogUtil. Ejecutar los procedimientos anteriores, verá los resultados que se muestran a continuación en la figura.

===== ===== simulación de un método genérico 
que soy un perro
 ===== ===== método común analógico de dos 
===== ==== simulación de un método general = 
corro rápidamente
 ===== ===== método común analógico de dos

Mediante la ejecución de los resultados mostrados por encima del punto de vista, difícil encontrar un agente dinámico que puede ser desacoplamiento muy flexible. En general, cuando se utiliza un proxy generar proxy dinámico, a menudo no sucede por un proxy dinámico, por lo que no hay mucha importancia práctica. Por lo general, generar proxy dinámico del objeto de destino especificado.

Esta dinámica AOP proxy (Aspect Orient Programación, Programación Orientada a) se denomina proxy de AOP, el proxy se puede usar en lugar del objeto AOP objetivo, agente AOP contiene todos los métodos del objeto de destino. Sin embargo, hay diferencias en los métodos de la diana proxies objeto AOP: Proxy AOP en el método puede ser ejecutado antes de que el método de destino, a continuación, insertar algún tipo de procesamiento de propósito general.

método proxy AOP que comprende un método del objeto de destino incluido en el siguiente diagrama mostrado en la figura.

 

Supongo que te gusta

Origin www.cnblogs.com/jwen1994/p/12575284.html
Recomendado
Clasificación