Java Reflection-proxy-uri dinamice

folosind Java Reflection creați implementări dinamice ale interfețelor în timpul rulării. Faceți acest lucru folosind clasa java.lang.reflect.Proxy. Numele acestei clase este motivul pentru care mă refer la aceste implementări de interfață dinamică ca proxy-uri dinamice. Proxy-urile dinamice pot fi utilizate în mai multe scopuri diferite, de exemplu, conectarea bazei de date și gestionarea tranzacțiilor, obiecte machete dinamice pentru testarea unității și alte scopuri de interceptare a metodelor asemănătoare AOP.

crearea proxy-urilor

creați proxy-uri dinamice folosind metoda Proxy.newProxyInstance(). Metodele newProxyInstance() necesită 3 parametri:

  1. ClassLoader care este de a” încărca ” clasa proxy dinamic.
  2. o serie de interfețe de implementat.
  3. An InvocationHandler pentru a transmite toate metodele solicită proxy la.

Iată un exemplu:

după rularea acestui cod, variabila proxy conține o implementare dinamică a interfeței MyInterface. Toate apelurile către proxy vor fi redirecționate către implementarea handler a interfeței generale InvocationHandler. InvocationHandler sunt acoperite i secțiunea următoare.

InvocationHandler ‘ s

după cum am menționat mai devreme, trebuie să treceți o implementare InvocationHandler la metoda Proxy.newProxyInstance(). Toate apelurile metodei către proxy-ul dinamic sunt redirecționate către această implementare InvocationHandler. Iată cum arată interfața InvocationHandler :

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

Iată un exemplu de implementare:

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

parametrul proxy transmis metodei invoke() este obiectul proxy dinamic care implementează interfața. Cel mai adesea nu aveți nevoie de acest obiect.

obiectul Method trecut în metoda invoke() reprezintă metoda apelată pe interfața implementată de proxy-ul dinamic. Din obiectul Method puteți obține numele metodei, tipurile de parametri, tipul de returnare etc. Consultați textul despre metode pentru mai multe informații.

matricea Object args conține valorile parametrilor transmise proxy-ului atunci când a fost apelată metoda din interfața implementată. Notă: primitivele (int, long etc) din interfața implementată sunt înfășurate în omologii lor obiect (Integer, Long etc.).

cazuri de Utilizare cunoscute

proxy-urile dinamice sunt cunoscute a fi utilizate cel puțin în următoarele scopuri:

  • conectarea bazei de date și gestionarea tranzacțiilor
  • obiecte machete dinamice pentru testarea unității
  • adaptarea containerului DI la interfețele personalizate din fabrică
  • interceptarea metodei AOP

conexiunea bazei de date și gestionarea tranzacțiilor

cadrul de primăvară are un proxy de tranzacție care poate începe și comite / revoca o tranzacție pentru dvs. Cum funcționează acest lucru este descris mai detaliat în text conexiune avansată și delimitare și propagare a tranzacțiilor , așa că o voi descrie doar pe scurt. Secvența de apel devine ceva de-a lungul acestui lucru:

obiecte machete dinamice pentru testarea unității

instrumentele de testare Butterfly utilizează proxy-uri dinamice pentru a implementa cioturi dinamice, batjocuri și proxy-uri pentru testarea unității. Când testați o clasă A care utilizează o altă clasă B (interfață într-adevăr), puteți trece o implementare simulată a lui B în A în loc de un B real. Toate apelurile de metodă pe B sunt acum înregistrate și puteți seta ce valori de returnare trebuie să returneze mock B.

în plus, instrumentele de testare a fluturilor vă permit să înfășurați un B real într-un mock B, astfel încât toate apelurile de metodă pe mock să fie înregistrate și apoi redirecționate către B real.acest lucru face posibilă verificarea metodelor care au fost apelate pe un B Real funcțional. de exemplu, dacă testați un DAO, puteți înfășura conexiunea bazei de date într-o mock. DAO nu va vedea diferența, iar DAO poate citi/scrie date în baza de date ca de obicei, deoarece mock transmite toate apelurile către baza de date. Dar acum Puteți verifica prin mock dacă DAO folosește conexiunea în mod corespunzător, de exemplu dacă connection.close() este apelat (sau nu este apelat), dacă vă așteptați la asta. În mod normal, acest lucru nu este posibil să se determine din valoarea returnată a unui DAO.

adaptarea containerului DI la interfețele personalizate din fabrică

containerul fluture al containerului de injecție dependență are o caracteristică puternică care vă permite să injectați întregul recipient în fasole produsă de acesta. Dar, din moment ce nu doriți o dependență de interfața containerului, containerul este capabil să se adapteze la o interfață personalizată din fabrică a designului dvs. Ai nevoie doar de interfață. Nici o implementare. Astfel, interfața din fabrică și clasa dvs. ar putea arăta așa:

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

când clasa MyAction apelează metode pe instanța IMyFactory injectată în constructorul său de către container, apelurile metodei sunt traduse în apeluri către metoda IContainer.instance(), care este metoda pe care o utilizați pentru a obține instanțe din container. În acest fel, un obiect poate folosi Butterfly Container ca fabrică în timpul rulării, mai degrabă decât să aibă dependențe injectate în sine la momentul creării. Și asta fără a avea dependențe de orice interfață specifică Butterfly Container.

interceptarea metodei AOP

cadrul de primăvară face posibilă interceptarea apelurilor metodei către un bean dat, cu condiția ca bean să implementeze o anumită interfață. Cadrul de primăvară înfășoară fasolea într-un proxy dinamic. Toate apelurile către bean sunt apoi interceptate de proxy. Proxy-ul poate decide să apeleze alte metode pe alte obiecte, fie înainte, în loc de, sau după delegarea apelului metoda de fasole înfășurat.

Lasă un răspuns

Adresa ta de email nu va fi publicată.