Middle
Milliseid proxy-serverite tüüpe te tead?
sobes.tech AI
Vastus AI-lt
Java-s on järgmised proxy tüübid:
-
Statiline (Static Proxy): Rakendatakse, luues eraldi katteklassi, mis sisaldab viidet tegelikule objekti ja edastab talle meetodite kutsed, lisades oma loogika (nt logimine, autoriseerimine).
// Liides interface Service { void doSomething(); } // Tõeline objekt class RealService implements Service { @Override public void doSomething() { System.out.println("Tõeline tegevus"); } } // Statiline proxy class StaticServiceProxy implements Service { private final Service realService; public StaticServiceProxy(Service realService) { this.realService = realService; } @Override public void doSomething() { System.out.println("Enne tõelise meetodi kutsumist"); realService.doSomething(); System.out.println("Pärast tõelise meetodi kutsumist"); } } -
Dünaamiline (Dynamic Proxy): Loobub jooksvalt Reflection API kasutades ja nõuab, et proxy objekt rakendaks vähemalt ühte liidest. Võimaldab genereerida proxy mitmele klassile, mis rakendavad sama liidest, ilma eraldi klassita igaüks.
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // Kutsuja käsitleja dünaamilistele proxy-dele class DynamicServiceInvocationHandler implements InvocationHandler { private final Object target; // Sihtobjekt public DynamicServiceInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Enne meetodi kutsumist " + method.getName()); Object result = method.invoke(target, args); // Sihtobjekti meetodi kutsumine System.out.println("Pärast meetodi kutsumist " + method.getName()); return result; } } // Näide kasutamisest (vastavalt statilise proxy näidisele Service liidese puhul) // Service realService = new RealService(); // Service proxy = (Service) Proxy.newProxyInstance( // realService.getClass().getClassLoader(), // realService.getClass().getInterfaces(), // new DynamicServiceInvocationHandler(realService)); // proxy.doSomething(); -
CGLIB Proxy: Põhineb baitkoodi genereerimisel ega nõua liidese rakendamist. Võib proxy konkreetseid klasse (kui need ei ole final ja meetodid ei ole final). Mõnel juhul on see kiirem kui standardne dünaamiline proxy.
// Näide CGLIB kasutamisest (vajab kolmanda osapoole teeki) // public class RealService { // public void doSomething() { // System.out.println("Tõeline tegevus"); // } // } // 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("Enne meetodi kutsumist " + method.getName()); // Object result = proxy.invokeSuper(obj, args); // Superklassi meetod (originaalobjekt) // System.out.println("Pärast meetodi kutsumist " + method.getName()); // return result; // } // } // // Näide kasutamisest: // // Enhancer enhancer = new Enhancer(); // // enhancer.setSuperclass(RealService.class); // // enhancer.setCallback(new CglibServiceInterceptor()); // // RealService proxy = (RealService) enhancer.create(); // // proxy.doSomething();
Peamised erinevused:
| Proxy tüüp | Nõuab liidest | Generatsioon | Paindlikkus | Tõhusus | Rakendus |
|---|---|---|---|---|---|
| Statiline | Jah | Käsitsi | Madal (üksiklassi jaoks) | Kõrge | Lihtsad juhtumid, kui struktuur on teada |
| Dünaamiline | Jah | Käivituse ajal | Kõrge (liideste jaoks) | Keskmine | Üldine loogika liideste jaoks, AOP |
| CGLIB | Ei | Käivituse ajal | Kõrge (klassidele) | Kõrge | AOP, proxy klassid ilma liidesteta |