Kokius proxy serverių tipus žinote?
sobes.tech AI
Atsakymas iš AI
Java egzistuoja šios rūšys proxy:
-
Statinis (Static Proxy): Įgyvendinamas sukuriant atskirą apvalkalo klasę, kuri turi nuorodą į tikrąjį objektą ir deleguoja jam metodų iškvietimus, pridėdama savo logiką (pvz., žurnalavimą, autorizaciją).
// Sąsaja interface Service { void doSomething(); } // Tikrasis objektas class RealService implements Service { @Override public void doSomething() { System.out.println("Tikras veiksmas"); } } // Statinis proxy class StaticServiceProxy implements Service { private final Service realService; public StaticServiceProxy(Service realService) { this.realService = realService; } @Override public void doSomething() { System.out.println("Prieš kviečiant tikrą metodą"); realService.doSomething(); System.out.println("Po kviečiant tikrą metodą"); } } -
Dinaminis (Dynamic Proxy): Sukuriamas vykdymo metu naudojant Reflection API ir reikalauja, kad proxy objektas įgyvendintų bent vieną sąsają. Leidžia generuoti proxy daugeliui klasių, įgyvendinančių tą patį sąsają, be atskiros klasės kiekvienam.
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // Kviečiančiojo apdorotojas dinamiškam proxy class DynamicServiceInvocationHandler implements InvocationHandler { private final Object target; // Tikslinis objektas public DynamicServiceInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Prieš metodo kvietimą " + method.getName()); Object result = method.invoke(target, args); // Tikslinio objekto metodo iškvietimas System.out.println("Po metodo kvietimo " + method.getName()); return result; } } // Pavyzdys naudojimo (sąsajai Service iš statinio proxy pavyzdžio) // Service realService = new RealService(); // Service proxy = (Service) Proxy.newProxyInstance( // realService.getClass().getClassLoader(), // realService.getClass().getInterfaces(), // new DynamicServiceInvocationHandler(realService)); // proxy.doSomething(); -
CGLIB Proxy: Pagrįstas baitkodo generavimu ir nereikalauja įgyvendinti sąsajos. Gali proxy konkrečius klases (jei jos nėra finalinės ir metodai nėra finaliniai). Kai kuriais atvejais yra efektyvesnis nei standartinis dinaminis proxy.
// Pavyzdys naudojimo su CGLIB (reikalauja trečiosios šalies bibliotekos) // public class RealService { // public void doSomething() { // System.out.println("Tikras veiksmas"); // } // } // import net.sf.cglib.proxy.MethodInterceptor; // import net.sf.cglib.proxy.MethodProxy; // import net.sf.cglib.proxy.Enhancer; // class CglibServiceInterceptor implements MethodInterceptor { // @Override // public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { // System.out.println("Prieš metodo kvietimą " + method.getName()); // Object result = proxy.invokeSuper(obj, args); // Superklasės metodo iškvietimas (originalus objektas) // System.out.println("Po metodo kvietimo " + method.getName()); // return result; // } // } // // Pavyzdys naudojimo: // // Enhancer enhancer = new Enhancer(); // // enhancer.setSuperclass(RealService.class); // // enhancer.setCallback(new CglibServiceInterceptor()); // // RealService proxy = (RealService) enhancer.create(); // // proxy.doSomething();
Pagrindiniai skirtumai:
| Proxy tipas | Reikalauja sąsajos | Generavimas | Lankstumas | Našumas | Taikymas |
|---|---|---|---|---|---|
| Statinis | Taip | Rankiniu būdu | Mažas (kiekvienam klasiui) | Aukštas | Paprasti atvejai, kai struktūra žinoma |
| Dinaminis | Taip | Vykdymo metu | Aukštas (sąsajoms) | Vidutinis | Bendroji logika sąsajoms, AOP |
| CGLIB | Nėra | Vykdymo metu | Aukštas (klasėms) | Aukštas | AOP, proxy klasių be sąsajų naudojimas |