Co to jest przypadek użycia dynamicznego serwera proxy?Co to są klasy Dynamic Proxy i dlaczego miałbym je używać?
Jak odnoszą się do generacji i odbicia kodu bajtowego?
Dowolna zalecana lektura?
Co to jest przypadek użycia dynamicznego serwera proxy?Co to są klasy Dynamic Proxy i dlaczego miałbym je używać?
Jak odnoszą się do generacji i odbicia kodu bajtowego?
Dowolna zalecana lektura?
Gorąco polecam ten resource.
Przede wszystkim musisz zrozumieć, co jest wzorcem użycia proxy.Pamiętaj, że głównym zamiarem proxy jest kontrolowanie dostępu do obiektu docelowego w celu uzyskania dostępu do obiektu docelowego . Kontrola dostępu obejmuje synchronizację, uwierzytelnianie, dostęp zdalny (RPC), leniwe tworzenie wystąpień (Hibernate, Mybatis), AOP (transakcja).
W przeciwieństwie do statycznego proxy, dynamiczne proxy generuje kod bajtowy, który wymaga odbicia Java w czasie wykonywania. Dzięki dynamice nie musisz tworzyć klasy proxy, co może prowadzić do większej wygody.
Klasa java.lang.reflect.Proxy
umożliwia dynamiczne wdrażanie interfejsów poprzez obsługę wywołań metod w postaci InvocationHandler
. Jest uważany za część obiektu do refleksji języka Java, ale nie ma nic wspólnego z generowaniem kodu bajtowego.
Słońce ma a tutorial o korzystaniu z klasy Proxy. Google helps, too.
Jednym z przypadków użycia jest hibernacja - daje obiekty implementujące interfejs klas modeli, ale w ramach programów pobierających i ustawiających znajduje się kod związany z db. To znaczy. używasz ich tak, jakby były po prostu POJO, ale w rzeczywistości wiele się dzieje pod osłoną.
Na przykład - po prostu wywołujemy getter z leniwie ładowanej właściwości, ale tak naprawdę właściwość (prawdopodobnie cała duża struktura obiektu) zostaje pobrana z bazy danych. Aby uzyskać więcej informacji, należy sprawdzić bibliotekę cglib, aby uzyskać więcej informacji.
klasa dynamiczna Pełnomocnik to klasa realizuje lista interfejsów określone w czasie pracy tak, że wariant a wywołanie przez jednym z interfejsów na przykład klasy będą zakodowane wysłana do innego obiekt przez jednolity interfejs. Może być to użyte do utworzenia bezpiecznego obiektu proxy typu dla listy interfejsów bez potrzeby wstępnego generowania klasy proxy. Dynamiczne proxy klasy są użyteczne dla aplikacji lub biblioteki, które muszą zapewniać odbieranie bezpiecznych typów wywołań typuna obiektach, które oferują interfejsy API interfejsu .
Dobra odpowiedź, a dobrym przykładem tej samej rzeczy jest Wiosna Remoting, który ma wbudowane możliwości serwera proxy dla HTTP, RMI, EJB i JMS . – Robin
właśnie wymyślił jakieś ciekawe zastosowanie dla dynamicznego proxy.
Mieliśmy problemy z niekrytyczną usługą, która jest powiązana z inną zależną usługą i chcieliśmy zbadać sposoby zachowania odporności na awarie, gdy ta zależna usługa staje się niedostępna.
Tak więc napisałem LoadSheddingProxy, który przyjmuje dwóch uczestników - jeden jest zdalnym imp dla "normalnej" usługi (po wyszukiwaniu JNDI). Drugi obiekt to "sztuczny" impond zrzucający obciążenie. Istnieje prosta logika otaczająca każdą metodę invoke, która łapie limity czasu i przenosi się do manekina przez określony czas, zanim spróbujesz ponownie. Oto jak go używać:
// This is part of your ServiceLocator class
public static MyServiceInterface getMyService() throws Exception
{
MyServiceInterface loadShedder = new MyServiceInterface() {
public Thingy[] getThingys(Stuff[] whatever) throws Exception {
return new Thingy[0];
}
//... etc - basically a dummy version of your service goes here
}
Context ctx = JndiUtil.getJNDIContext(MY_CLUSTER);
try {
MyServiceInterface impl = ((MyServiceHome) PortableRemoteObject.narrow(
ctx.lookup(MyServiceHome.JNDI_NAME),
MyServiceHome.class)).create();
// Here's where the proxy comes in
return (MyService) Proxy.newProxyInstance(
MyServiceHome.class.getClassLoader(),
new Class[] { MyServiceInterface.class },
new LoadSheddingProxy(MyServiceHome.JNDI_NAME, impl, loadShedder, 60000)); // 10 minute retry
} catch (RemoteException e) { // If we can't even look up the service we can fail by shedding load too
logger.warn("Shedding load");
return loadShedder;
} finally {
if (ctx != null) {
ctx.close();
}
}
}
A oto proxy:
public class LoadSheddingProxy implements InvocationHandler {
static final Logger logger = ApplicationLogger.getLogger(LoadSheddingProxy.class);
Object primaryImpl, loadDumpingImpl;
long retry;
String serviceName;
// map is static because we may have many instances of a proxy around repeatedly looked-up remote objects
static final Map<String, Long> servicesLastTimedOut = new HashMap<String, Long>();
public LoadSheddingProxy(String serviceName, Object primaryImpl, Object loadDumpingImpl, long retry)
{
this.serviceName = serviceName;
this.primaryImpl = primaryImpl;
this.loadDumpingImpl = loadDumpingImpl;
this.retry = retry;
}
public Object invoke(Object obj, Method m, Object[] args) throws Throwable
{
try
{
if (!servicesLastTimedOut.containsKey(serviceName) || timeToRetry()) {
Object ret = m.invoke(primaryImpl, args);
servicesLastTimedOut.remove(serviceName);
return ret;
}
return m.invoke(loadDumpingImpl, args);
}
catch (InvocationTargetException e)
{
Throwable targetException = e.getTargetException();
// DETECT TIMEOUT HERE SOMEHOW - not sure this is the way to do it???
if (targetException instanceof RemoteException) {
servicesLastTimedOut.put(serviceName, Long.valueOf(System.currentTimeMillis()));
}
throw targetException;
}
}
private boolean timeToRetry() {
long lastFailedAt = servicesLastTimedOut.get(serviceName).longValue();
return (System.currentTimeMillis() - lastFailedAt) > retry;
}
}
Nicea wyjaśnienie tutaj https://opencredo.com/dynamic-proxies-java/ – Bala