Sobes.tech
Middle

Кайсы түрдөгү прокси-серверлерди билесиз?

sobes.tech AI

AIден жооп

Javaда төмөнкү түрлөрү бар:

  • Статикалык (Static Proxy): Бул жеке класс-обертка түзүү аркылуу ишке ашырылат, ал реалдуу объектке шилтемени камтыйт жана анын методдорун чакырат, өзүнүн логикасын кошуп (мисалы, логгинг, авторизация).

    // Интерфейс
    interface Service {
        void doSomething();
    }
    
    // Реалдуу объект
    class RealService implements Service {
        @Override
        public void doSomething() {
            System.out.println("Реалдуу аракет");
        }
    }
    
    // Статикалык прокси
    class StaticServiceProxy implements Service {
        private final Service realService;
    
        public StaticServiceProxy(Service realService) {
            this.realService = realService;
        }
    
        @Override
        public void doSomething() {
            System.out.println("Реалдуу методду чакырганга чейин");
            realService.doSomething();
            System.out.println("Реалдуу методду чакыргандан кийин");
        }
    }
    
  • Динамикалык (Dynamic Proxy): Аткаруу учурунда түзүлөт, Reflection API колдонуп жана прокси объект кеминде бир интерфейсти ишке ашырган болушу керек. Бир интерфейсти ишке ашырган көптөгөн класстар үчүн прокси түзүүгө мүмкүндүк берет, ар бир үчүн өзүнчө класс түзбөстөн.

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    // Dynamic Proxy үчүн иштетүүчү
    class DynamicServiceInvocationHandler implements InvocationHandler {
        private final Object target; // Мақсаттуу объект
    
        public DynamicServiceInvocationHandler(Object target) {
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("Методду чакырганга чейин " + method.getName());
            Object result = method.invoke(target, args); // Мақсаттуу объекттин методун чакыруу
            System.out.println("Методду чакыргандан кийин " + method.getName());
            return result;
        }
    }
    
    // Колдонуу мисалы (Service интерфейси үчүн)
    // Service realService = new RealService();
    // Service proxy = (Service) Proxy.newProxyInstance(
    //     realService.getClass().getClassLoader(),
    //     realService.getClass().getInterfaces(),
    //     new DynamicServiceInvocationHandler(realService));
    // proxy.doSomething();
    
  • CGLIB Proxy: Байткод түзүү негизделген жана интерфейсти ишке ашыруусун талап кылбайт. Конкреттүү класстарды прокси кылышы мүмкүн (эгер алар финалдык эмес жана методдору финалдык эмес болсо). Айрым сценарийлерде стандарттык динамикалык проксиге караганда натыйжалуу.

    // CGLIB колдонуу мисалы (сырткы китепкана талап кылынат)
    // public class RealService {
    //     public void doSomething() {
    //         System.out.println("Реалдуу аракет");
    //     }
    // }
    
    // 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("Методду чакырганга чейин " + method.getName());
    //         Object result = proxy.invokeSuper(obj, args); // Ата-эне класстын (оригиналдуу объект) методун чакыруу
    //         System.out.println("Методду чакыргандан кийин " + method.getName());
    //         return result;
    //     }
    // }
    
    // // Колдонуу мисалы:
    // // Enhancer enhancer = new Enhancer();
    // // enhancer.setSuperclass(RealService.class);
    // // enhancer.setCallback(new CglibServiceInterceptor());
    // // RealService proxy = (RealService) enhancer.create();
    // // proxy.doSomething();
    

Негизги айырмачылыктар:

Түрү Интерфейс талап кылынат Генерация Ийкемдүүлүк Аткаруу Колдонуу
Статикалык Ооба Кол менен Төмөн (ар бир класс үчүн) Жогорку Жөнөкөй учурлар, структура белгилүү болсо
Динамикалык Ооба Аткаруу учурунда Жогорку (интерфейстер үчүн) Орто Жалпы логика үчүн, AOP
CGLIB Жок Аткаруу учурунда Жогорку (класстар үчүн) Жогорку AOP, интерфейстерсиз класстарды прокси кылуу