Java Dynamic Proxy
Los proxy dinámicos fueron introducidos en la API de Java 1.3 agregando múltiples funcionalidades a la plataforma Java. En este post pretendo enseñarles algunos usos de los proxy dinámicos y cómo implementar uno sencillo.
Primero tienen que conocer la definición de proxy y sus posibles usos, que ya fueron descritas en un post anterior, puedes revisarlo antes de continuar: Patrones de Diseño: Proxy
Primero debemos conocer las clases que hacen posible la implementación de Dynamic Proxy en la API de Java, estas son java.lang.reflect.Proxy
y java.lang.reflect.InvocationHandler
, además debes tener conceptos básicos de Reflexión (sólo para la invocación de métodos).
java.lang.reflect.Proxy
Para crear un objeto Proxy debes utilizar la clase java.lang.reflect.Proxy
de la siguiente forma:
1 | Object obj = Proxy.newProxyInstance(classLoader, interfaces, handler); |
Donde:
- classLoader: classloader que contiene la definición de las interfaces que componen el objeto target (o RealSubject).
- interfaces: Arreglo con la definición de las interfaces que implementa el objeto target (o RealSubject).
- handler: Esta es la clase que nos permitirá implementar el Proxy, es la clase que contiene la lógica de negocio del Proxy.
java.lang.reflect.InvocationHandler
Esta interfaz debe ser implementada y tenemos el método invoke que hará las veces de interceptor, es aquí donde debemos escribir nuestra lógica de negocio.
1 | public interface InvocationHandler { |
Reglas para crear un Dynamic Proxy
- El objeto a “proxiar” debe tener una interfaz, no una clase concreta o abstracta, una Interfaz.
- El arreglo de Interfaces no debe contener interfaces duplicadas.
- Todas las interfaces deben ser visibles en el classloader que se esta utilizando (usado en la construcción del Proxy).
- Las interfaces del proxy no deben tener conflictos de métodos. Ver la especificación de Lenguaje Java sobre sobre-escritura de métodos.
Ejemplo Práctico
Veamos un ejemplo práctico de la implementación de un proxy dinámico usando la API de Java:
1 | public interface Calculadora { |
Ahora veamos la implementación de Calculadora:
1 | public class CalculadoraImpl implements Calculadora { |
Supongamos que estas clases ya están creadas y necesitamos agregar un par de funcionalidades sin tener que tocar el código ya existente. La primera funcionalidad es validar que los números a y b sean mayores a 0 y la segunda funcionalidad es loggear los parámetros de entrada.
1 | public class CalculadoraProxyFactory implements InvocationHandler { |
Como podrán ver en el ejemplo, en el método invoke se hace el control y el log sobre los argumentos que entran al método suma del RealSubject. Además para simplificar la creación del Proxy, se implementó un method-factory que crea el proxy dinámico (método proxyFactory).
Ahora el test unitario que prueba el funcionamiento del Proxy:
1 | public class CalculadoraProxyFactoryTest { |
La salida de este test a la consola con maven es la siguiente:
1 | ------------------------------------------------------- |
Espero que les haya sido útil, en un próximo post escribiré sobre otras formas de crear Proxy. Deje su comentario.
Java Dynamic Proxy