Zgodnie z dokumentacją :
[
java.lang.reflect.
]Proxy
zapewnia statyczne metody tworzenia dynamicznych klas i instancji proxy, a także stanowi nadklasę wszystkich dynamicznych klas proxy tworzonych przez te metody.
newProxyMethod
Metoda (odpowiedzialny za generowanie dynamicznych proxy) ma następujący podpis:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
Niestety, uniemożliwia to generowanie dynamicznego serwera proxy, który rozszerza określoną klasę abstrakcyjną (zamiast implementować określone interfejsy). Ma to sens, biorąc pod uwagę, że java.lang.reflect.Proxy
jest to „nadklasa wszystkich dynamicznych serwerów proxy”, zapobiegając w ten sposób innej klasie bycia nadklasą.
Czy w związku z tym istnieją alternatywy, java.lang.reflect.Proxy
które mogą generować dynamiczne serwery proxy, które dziedziczą z określonej klasy abstrakcyjnej, przekierowując wszystkie wywołania metod abstrakcyjnych do modułu obsługi wywołań?
Na przykład załóżmy, że mam klasę abstrakcyjną Dog
:
public abstract class Dog {
public void bark() {
System.out.println("Woof!");
}
public abstract void fetch();
}
Czy jest klasa, która pozwala mi wykonywać następujące czynności?
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
źródło
proxyFactory.setHandler()
jest przestarzałe. Proszę użyćproxy.setHandler
.W takim przypadku możesz mieć program obsługi proxy, który przekieruje wywołania do istniejących metod Twojej klasy abstrakcyjnej.
Oczywiście będziesz musiał to zakodować, jednak jest to dość proste. Aby utworzyć proxy, musisz dać mu plik
InvocationHandler
. Będziesz wtedy musiał tylko sprawdzić typ metody winvoke(..)
metodzie obsługi wywołania. Ale uwaga: będziesz musiał porównać typ metody z podstawowym obiektem powiązanym z twoim programem obsługi, a nie z zadeklarowanym typem twojej klasy abstrakcyjnej.Jeśli weźmiemy jako przykład twoją klasę psa, metoda invoke twojego programu obsługi wywołań może wyglądać następująco (z istniejącą skojarzoną podklasą psa o nazwie… no…
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 ? } }
Jest jednak coś, co każe mi się zastanawiać: mówiłem o
dog
przedmiocie. Ale ponieważ klasa Dog jest abstrakcyjna, nie możesz tworzyć instancji, więc masz istniejące podklasy. Ponadto, gdy rygorystyczna inspekcja kodu źródłowego proxy ujawnia, możesz odkryć (na Proxy.java:362), że nie jest możliwe utworzenie proxy dla obiektu klasy, który nie reprezentuje interfejsu).Tak więc, pomijając rzeczywistość , to, co chcesz zrobić, jest całkowicie możliwe.
źródło
Dog
(na przykład nie piszę wyraźniePoodle
klasy, która implementujefetch()
). Dlatego nie madog
zmiennej, na której można wywołać metody ... Przepraszam, jeśli się mylę, będę musiał przemyśleć to trochę więcej.java.lang.reflect.Proxy
), która robi to, czego potrzebuję.