Java Reflection-dynamické Proxy

pomocí Java Reflection vytvoříte dynamické implementace rozhraní za běhu. Činíte tak pomocí třídy java.lang.reflect.Proxy. Název této třídy je důvod, proč tyto implementace dynamického rozhraní označuji jako dynamické proxy. Dynamické proxy servery mohou být použity pro mnoho různých účelů, např. pro připojení k databázi a správu transakcí, dynamické falešné objekty pro testování jednotek a další účely zachycování metod podobných AOP.

vytvoření Proxy

dynamické proxy vytvoříte metodou Proxy.newProxyInstance(). Metody newProxyInstance() mají 3 parametry:

  1. ClassLoader , který má “načíst” dynamickou třídu proxy.
  2. pole rozhraní pro implementaci.
  3. An InvocationHandler pro přeposílání všech metod volání na proxy.

zde je příklad:

po spuštění tohoto kódu obsahuje proměnná proxy dynamickou implementaci rozhraní MyInterface. Všechna volání na proxy budou přesměrována na handler implementaci obecného rozhraní InvocationHandler. InvocationHandler je pokryta i další část.

InvocationHandler ‘ s

jak již bylo zmíněno, musíte předat implementaci InvocationHandler metodě Proxy.newProxyInstance(). Všechna volání metod do dynamického proxy serveru jsou předána této implementaci InvocationHandler. Zde je, jak vypadá rozhraní InvocationHandler :

public interface InvocationHandler{ Object invoke(Object proxy, Method method, Object args) throws Throwable;}

zde je příklad implementace:

public class MyInvocationHandler implements InvocationHandler{ public Object invoke(Object proxy, Method method, Object args) throws Throwable { //do something "dynamic" }}

parametr proxy předaný metodě invoke() je dynamický objekt proxy implementující rozhraní. Nejčastěji tento objekt nepotřebujete.

objekt Method předaný do metody invoke() představuje metodu nazývanou na rozhraní, které implementuje dynamický proxy. Z objektu Method můžete získat název metody, typy parametrů, typ návratu atd. Další informace naleznete v textu o metodách.

pole Object args obsahuje hodnoty parametrů předané serveru proxy, když byla vyvolána metoda v implementovaném rozhraní. Poznámka: Primitiva (int, long atd.) v implementovaném rozhraní jsou zabalena do jejich objektových protějšků (Integer, Long atd.).).

známé případy použití

je známo, že dynamické proxy servery jsou používány alespoň pro následující účely:

  • Database Connection and Transaction Management
  • dynamické falešné objekty pro testování jednotek
  • přizpůsobení kontejneru DI na vlastní tovární rozhraní
  • AOP-like method Interception

Database Connection and Transaction Management

Spring framework má transakční proxy, který může spustit a odevzdat / vrátit transakci za vás. Jak to funguje, je podrobněji popsáno v textu Advanced Connection and Transaction Demarcation and Propagation, takže to popíšu jen stručně. Sekvence volání se stává něco podél tohoto:

dynamické falešné objekty pro testování jednotek

nástroje pro testování motýlů využívají dynamické proxy k implementaci dynamických pahýlů, výsměchů a proxy pro testování jednotek. Při testování třídy A, která používá jinou třídu B (rozhraní opravdu), můžete předat falešnou implementaci B do a místo skutečného B. Všechna volání metod na B jsou nyní zaznamenána a můžete nastavit, jaké návratové hodnoty má mock B vrátit.

dále nástroje pro testování motýlů umožňují zabalit skutečné B do falešného B, takže jsou zaznamenány všechny volání metod na maketu a poté předány skutečnému B. To umožňuje zkontrolovat, jaké metody byly volány na skutečném fungování B. například při testování DAO můžete zabalit připojení databáze do falešného. DAO neuvidí rozdíl a DAO může číst / zapisovat data do databáze jako obvykle, protože mock předává všechna volání do databáze. Nyní však můžete pomocí makety zkontrolovat, zda DAO používá připojení správně, například pokud je voláno connection.close() (nebo není voláno), pokud jste to očekávali. To obvykle není možné určit z návratové hodnoty DAO.

adaptace di kontejneru na vlastní tovární rozhraní

Dependency injection container Butterfly Container má výkonnou funkci, která umožňuje injektovat celý kontejner do jím vyrobených fazolí. Ale protože nechcete závislost na rozhraní kontejneru, kontejner se dokáže přizpůsobit vlastnímu továrnímu rozhraní vašeho návrhu. Potřebujete pouze rozhraní. Žádná implementace. Tovární rozhraní a vaše třída by tedy mohly vypadat takto:

public interface IMyFactory { Bean bean1(); Person person(); ...}

když třída MyAction volá metody na instanci IMyFactory vložené do jejího konstruktoru kontejnerem, volání metody jsou přeložena do volání na metodu IContainer.instance(), což je metoda, kterou používáte k získání instancí z kontejneru. Tímto způsobem může objekt použít Butterfly Container jako továrnu za běhu, spíše než jen proto, aby do sebe v době vytvoření vložil závislosti. A to bez závislosti na jakémkoli rozhraní specifickém pro Motýlí kontejner.

AOP-like method Interception

pružinový rámec umožňuje zachytit volání metody na danou bean za předpokladu, že bean implementuje nějaké rozhraní. Pružinový rámec zabalí fazole do dynamického proxy. Všechny hovory na bean jsou pak zachyceny proxy. Proxy se může rozhodnout volat jiné metody na jiných objektech buď před, namísto, nebo po delegování volání metody na zabalené fazole.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.