Selon la documentation :
[
java.lang.reflect.
]Proxy
fournit des méthodes statiques pour créer des classes et des instances proxy dynamiques, et c'est aussi la superclasse de toutes les classes proxy dynamiques créées par ces méthodes.
La newProxyMethod
méthode (chargée de générer les proxies dynamiques) a la signature suivante:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
Malheureusement, cela empêche de générer un proxy dynamique qui étend une classe abstraite spécifique (plutôt que d' implémenter des interfaces spécifiques). Cela a du sens, étant donné que java.lang.reflect.Proxy
c'est "la superclasse de tous les proxys dynamiques", empêchant ainsi une autre classe d'être la superclasse.
Par conséquent, existe-t-il des alternatives à java.lang.reflect.Proxy
cela qui peuvent générer des proxys dynamiques qui héritent d'une classe abstraite spécifique, redirigeant tous les appels vers les méthodes abstraites vers le gestionnaire d'invocation?
Par exemple, supposons que j'ai une classe abstraite Dog
:
public abstract class Dog {
public void bark() {
System.out.println("Woof!");
}
public abstract void fetch();
}
Y a-t-il un cours qui me permet de faire ce qui suit?
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
la source
proxyFactory.setHandler()
est obsolète. Veuillez utiliserproxy.setHandler
.Ce que vous pouvez faire dans un tel cas est d'avoir un gestionnaire de proxy qui redirigera les appels vers les méthodes existantes de votre classe abstraite.
Vous devrez bien sûr le coder, mais c'est assez simple. Pour créer votre proxy, vous devrez lui donner un fichier
InvocationHandler
. Vous n'aurez alors plus qu'à vérifier le type de méthode dans lainvoke(..)
méthode de votre gestionnaire d'appel. Mais attention: vous devrez vérifier le type de méthode par rapport à l'objet sous-jacent associé à votre gestionnaire, et non par rapport au type déclaré de votre classe abstraite.Si je prends comme exemple votre classe dog, la méthode d'invocation de votre gestionnaire d'invocation peut ressembler à ceci (avec une sous-classe dog associée existante appelée .. eh bien ...
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 ? } }
Cependant, il y a quelque chose qui m'interroge: j'ai parlé d'un
dog
objet. Mais, comme la classe Dog est abstraite, vous ne pouvez pas créer d'instances, vous avez donc des sous-classes existantes. En outre, comme le révèle une inspection rigoureuse du code source du proxy, vous pouvez découvrir (à Proxy.java:362) qu'il n'est pas possible de créer un proxy pour un objet de classe qui ne représente pas une interface).Donc, en dehors de la réalité , ce que vous voulez faire est parfaitement possible.
la source
Dog
(par exemple, je n'écris pas explicitement unePoodle
classe qui implémentefetch()
). Par conséquent, il n'y a pas dedog
variable sur laquelle invoquer les méthodes ... Désolé si je suis confus, je devrai y réfléchir un peu plus.java.lang.reflect.Proxy
) disponible qui fait ce dont j'ai besoin.