De acordo com a documentação :
[
java.lang.reflect.
]Proxy
fornece métodos estáticos para a criação de classes e instâncias de proxy dinâmico, e também é a superclasse de todas as classes de proxy dinâmico criadas por esses métodos.
O newProxyMethod
método (responsável por gerar os proxies dinâmicos) possui a seguinte assinatura:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
Infelizmente, isso impede que se gere um proxy dinâmico que estenda uma classe abstrata específica (em vez de implementar interfaces específicas). Isso faz sentido, considerando que java.lang.reflect.Proxy
é "a superclasse de todos os proxies dinâmicos", evitando assim que outra classe seja a superclasse.
Portanto, há alguma alternativa para java.lang.reflect.Proxy
que possa gerar proxies dinâmicos que herdam de uma classe abstrata específica, redirecionando todas as chamadas aos métodos abstratos para o manipulador de invocação?
Por exemplo, suponha que eu tenha uma classe abstrata Dog
:
public abstract class Dog {
public void bark() {
System.out.println("Woof!");
}
public abstract void fetch();
}
Existe uma classe que me permite fazer o seguinte?
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
fonte
proxyFactory.setHandler()
está obsoleto. Por favor, useproxy.setHandler
.O que você pode fazer nesse caso é ter um manipulador de proxy que redirecionará chamadas para métodos existentes de sua classe abstrata.
É claro que você terá que codificá-lo, mas é bastante simples. Para criar seu proxy, você terá que dar a ele um
InvocationHandler
. Você só terá que verificar o tipo de método noinvoke(..)
método do seu manipulador de invocação. Mas cuidado: você terá que verificar o tipo de método em relação ao objeto subjacente associado ao seu manipulador, e não em relação ao tipo declarado de sua classe abstrata.Se eu tomar como exemplo sua classe dog, o método invoke do manipulador de invocação pode ser parecido com este (com uma subclasse dog associada existente chamada ... bem ...
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 ? } }
No entanto, há algo que me mantém pensando: já falei sobre um
dog
objeto. Mas, como a classe Dog é abstrata, você não pode criar instâncias, portanto, existem subclasses. Além disso, como uma inspeção rigorosa do código-fonte do Proxy revela, você pode descobrir (em Proxy.java:362) que não é possível criar um Proxy para um objeto Classe que não represente uma interface).Portanto, fora da realidade , o que você quer fazer é perfeitamente possível.
fonte
Dog
(por exemplo, não estou escrevendo explicitamente umaPoodle
classe que implementafetch()
). Portanto, não há nenhumadog
variável para invocar os métodos ... Desculpe se estou confuso, terei que pensar um pouco mais.java.lang.reflect.Proxy
) disponível que faz o que eu preciso.