Según la documentación :
[
java.lang.reflect.
]Proxy
proporciona métodos estáticos para crear instancias y clases de proxy dinámicos, y también es la superclase de todas las clases de proxy dinámicas creadas por esos métodos.
El newProxyMethod
método (responsable de generar los proxies dinámicos) tiene la siguiente firma:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
Desafortunadamente, esto evita que uno genere un proxy dinámico que amplíe una clase abstracta específica (en lugar de implementar interfaces específicas). Esto tiene sentido, considerando que java.lang.reflect.Proxy
es "la superclase de todos los proxies dinámicos", evitando así que otra clase sea la superclase.
Por lo tanto, ¿hay alguna alternativa java.lang.reflect.Proxy
que pueda generar proxies dinámicos que hereden de una clase abstracta específica, redirigiendo todas las llamadas a los métodos abstractos al controlador de invocación?
Por ejemplo, supongamos que tengo una clase abstracta Dog
:
public abstract class Dog {
public void bark() {
System.out.println("Woof!");
}
public abstract void fetch();
}
¿Existe alguna clase que me permita hacer lo siguiente?
Dog dog = SomeOtherProxy.newProxyInstance(classLoader, Dog.class, h);
dog.fetch(); // Will be handled by the invocation handler
dog.bark(); // Will NOT be handled by the invocation handler
fuente
proxyFactory.setHandler()
es obsoleto. Utiliceproxy.setHandler
.Lo que puede hacer en tal caso es tener un controlador de proxy que redirigirá las llamadas a los métodos existentes de su clase abstracta.
Por supuesto, tendrá que codificarlo, sin embargo, es bastante simple. Para crear su Proxy, tendrá que darle un
InvocationHandler
. Luego, solo tendrá que verificar el tipo de método en elinvoke(..)
método de su controlador de invocación. Pero tenga cuidado: tendrá que comparar el tipo de método con el objeto subyacente asociado a su controlador, y no con el tipo declarado de su clase abstracta.Si tomo como ejemplo su clase de perro, el método de invocación de su controlador de invocación puede verse así (con una subclase de perro asociada existente llamada .. bueno ...
dog
)public void invoke(Object proxy, Method method, Object[] args) { if(!Modifier.isAbstract(method.getModifiers())) { method.invoke(dog, args); // with the correct exception handling } else { // what can we do with abstract methods ? } }
Sin embargo, hay algo que me deja pensando: he hablado de un
dog
objeto. Pero, como la clase Dog es abstracta, no puede crear instancias, por lo que tiene subclases existentes. Además, como revela una inspección rigurosa del código fuente de Proxy, puede descubrir (en Proxy.java:362) que no es posible crear un Proxy para un objeto Class que no representa una interfaz).Entonces, más allá de la realidad , lo que quieres hacer es perfectamente posible.
fuente
Dog
(por ejemplo, no estoy escribiendo explícitamente unaPoodle
clase que implementefetch()
). Por lo tanto, no hay ningunadog
variable sobre la que invocar los métodos ... Lo siento si me confundo, tendré que pensarlo un poco más.java.lang.reflect.Proxy
) disponible que haga lo que necesito.