Основы: это требуют объектно-ориентированных дизайнерских идей, полиморфных идей и идей рефлексии;
Появление механизма динамического прокси -сервера Java позволяет разработчикам Java динамически получать классы прокси без необходимости вручную писать классы прокси. Класс прокси отвечает за отправление всех вызовов методов в объект делегата, чтобы отразить выполнение. В процессе выполнения отправки разработчики также могут регулировать объект делегата и его функции по мере необходимости. Это очень гибкая и гибкая прокси -структура. Прочитав эту статью, у читателей будет более глубокое понимание механизма динамического прокси -сервера Java. В этой статье сначала анализируется код, основанный на операционном механизме и характеристиках динамического прокси -сервера Java и вычитает внутреннюю реализацию классов динамической генерации.
Основные понятия и классификация модели агента
Прокси -режим: предоставляет прокси для других объектов для управления доступом к этому объекту. Прокси-объект действует как посредник и может удалять услуги или добавлять дополнительные услуги, или цитировать других: «Класс прокси отвечает за предварительные сообщения для класса делегатов, фильтрацию сообщений и пересылки сообщений и выполнение последующей обработки после того, как сообщение выполняется классом делегата».
Сценарии применения режима агента в разработке
Удаленный прокси: предоставляет репрезентативные объекты LAN для объектов различных географических регионов.
Виртуальный агент: задерживайте объекты, которые потребляют много ресурсов по мере необходимости, и создают их, когда они действительно необходимы. Например, текст отображается сначала, а затем изображение отображается на веб -странице.
Защитный агент: управляет правами доступа разных пользователей. Например: только после успешной регистрации клиента можно добавить, удалять, изменять и проверить операции.
Умный справочный агент: предоставляет дополнительные услуги целевому агенту.
Как реализовать режим прокси
Какой из них лучше реализовать динамический прокси, используя наследование и агрегацию!
Общедоступный интерфейс {public void move ();} public Class Car реализует Moviable {@Override public void move () {try {thread.sleep (new random (). NextInt (1000)); System.out.println ("... rival ...");} catch (requarptenException e) {// todo auto-gate-catcher atecrint e.crint e.printst electack e); CAR2 Extens Car {@Override public void move () {// разделить код, увеличить бизнес -логику Long StartTime = System.currentTimeMillis (); System.out.println («Автомобиль начинает двигаться ...»); super.move (); Long Endtime = System.currentTimillis (); "+(EndTime-starttime)+" ms ");}}Метод наследования для реализации прокси -сервера
Moveablecar2=newCar2();
car2.move();
Метод агрегации реализует прокси
Carcar=newCar();
Moveablem=newCar3(car);
m.move();
Суммировать
Метод наследования недостаточно гибкий. Когда функции наложены, вы можете раздувать класс прокси -класса;
Используя агрегацию, агенты могут быть переданы друг другу, а прокси -сервер может быть гибко объединен;
открытый класс CarlogProxy Extends CAR {@Override public void move () {// разделить код и увеличить бизнес -логику long startTime = System.currentTimeMillis (); System.out.println ("Login Start ..."); Super.Move (); Long Endtime = System.CurrentTimeMillis (); System.out.println (neply end '); ") Cartimeproxy реализует Moviable {public cartimeproxy (Car Car) {super (); this.car = car;} private carcar; @Override public void move () {// отделить код и добавить бизнес -логику Long StartTime = System.currentTimemilis (); System.out.println («Автомобиль начинает ездить ...»); EndTime = System.CurrentTimeMillis (); System.out.println («Автомобиль заканчивается для управления ... время:«+(endtime-starttime)+"ms");}}@test: car Car = new Car (); cartimeproxy ctp = new cartimeproxy (car); carlogproxy clp = newarlogproxy (ctpove); Также передайте экземпляры прокси -сервера друг к другу через интерфейсы CarlogProxy CLP1 = новый CarlogProxy (CAR); CartimeProxy CTP1 = новый картимепокси (CLP1); CTP1.Move ();Dynk Dynamic Proxy и Cglib Dynamic Proxy
JDK Dynamic Proxy
Реализация агента
Что следует сделать, если разные объекты хотят реализовать класс прокси с той же функцией?
В настоящее время вы можете попытаться интегрировать его в один и тот же класс прокси ------- Динамический прокси: реализация прокси для разных классов/различных методов;
Общий процесс заключается в следующем:
Класс динамического прокси -сервера Java расположен в пакете java.lang.reflect, который, как правило, в основном включает в себя следующие два класса:
(1) InterfaceInvocationHandler: только один метод определяется в этом интерфейсе publicObjectInvoke (ObjectObj, MethodMethod, Object [] args)
OBJ: Обычно относится к классу прокси
Метод: это метод прокси -сервера
ARGS является массивом параметров для этого метода.
Этот абстрактный метод реализуется динамически в классе прокси.
(2) Прокси: этот класс является динамическим прокси -классом
statixObjectnewProxyInstance(ClassLoaderloader,Class[]interfaces,InvocationHandlerh)
Возвращает экземпляр класса гликозида, и возвращаемый класс прокси может использоваться в качестве класса прокси (вы можете использовать метод, объявленный в интерфейсе классом Proxy);
Пример реализации:
@ TimeHandler public Class TimeHandler реализует vocationHandler {public TimeHandler (объект цели) {super (); this.Target = target;} private objectTarget;/** Параметры:* Прокси -прокси -объект* Метод прокси -объекта* Арг Параметр** Возвращаемый метод объекта. startTime = System.CurrentTimeMillis (); System.out.println («Автомобиль начинает управлять ...»); method.invoke (target); long endtime = system.currenttimemillis (); System.out.println ("автомобиль заканчивается, чтобы управлять ... Время:"+(condTimeTime)+"MS"); @Интерфейс Proxy Class Public Interface Moviable {public void move ();}@класс прокси Общедоступный класс автомобиль реализует подвижную {@override public void move () {try {thread.sleep (new random (). nextint (1000)); System.out.println ("... riving ...");} catch (urruptEdexception e) {// todo Auto-Generated CatchTrace E.printStcktrace ();@тест
Общественный тест класса { / *** JDK Dynamic Proxy Test Class* / public static void main (string [] args) {car car = new Car (); VocationHandler h = new TimeHandler (автомобиль); Класс <?> Cls = car.getClass (); /** Загрузчик загрузчика* Интерфейсы реализуют интерфейс* hlocationhandler*/ подвижный m = (подвижный) proxy.newproxyinstance (cls.getclassloader (), cls.getInterfaces (), h); M.Move (); }}&& результаты теста
Краткое содержание
Динамика - это такой класс:
Это класс, сгенерированный во время выполнения. Этот класс должен реализовать набор интерфейсов. При использовании динамических прокси -классов необходимо реализовать интерфейс InvocationHandler.
Общие шаги для динамического прокси JDK
1. Создайте класс, который реализует интерфейс vlocationhandler, который должен реализовать indoke ()
2. Создайте класс прокси и интерфейс
3. Позвоните в статический метод Proxy для создания класса прокси
NewProxyInstance (ClassLoaderLoder, Class [] Интерфейсы, vococationHandlerh)
4. Вызовы методы через прокси
Реализация динамического прокси CGLIB
Реализация агента
@Introducing cglib-node-2.2.jar пакет
@Cglibproxy class class реализует интерфейс метод Intercept: переписать метод перехвата
Общедоступный класс CglibProxy реализует MethodInterceptor {private Enhancerenhancer = new Enhancer (); Public Object getProxy (Class CL) {// Установить класс, который создает подкласс Enhancer.setSuperClass (Cl); Enhancer.SetCallback (This); return Enhancer.create ();******************************* Метод ARGS* Экземпляр Proxy Class**/@переопределить публичный объект Intercept (Object obj, Method M, Object [] Args, MethodProxy Proxy) Throws Throwable {System.out.println ("rougin start ..."); // Класс Proxy называет метод родительского класса. нулевой;}}@Proxy Class Train
открытый класс поезда {public void move () {System.out.println («Поезд ездит ...»); }}@Test Class
Общественный тест класса { / *** CGLIBProxy Dynamic Proxy Class* / Public Static Void Main (String [] args) {cglibproxy proxy = new cglibproxy (); Поезд T = (поезда) proxy.getProxy (train.class); t.move (); }}## Результаты теста:
Краткое содержание
Общие шаги по реализации динамического прокси с использованием cglibproxy
1. Создайте класс для реализации интерфейсного метода Interceptor и переопределить метод перехвата
2. Создайте прокси -класс
3. Вызовите пользовательский метод класса Proxy, чтобы получить экземпляр прокси
4. Вызовите метод, который должен быть выполнен экземпляром прокси -сервера
Сравнительное резюме
JDK Dynamic Proxy
1. Только прокси -классы, которые реализуют интерфейсы
2. Классы без интерфейса не могут реализовать динамический прокси для JDK
CGLIB Dynamic Proxy
1. Реализация прокси для занятий
2. Сгенерируйте подкласс для целевого класса выполнения и используйте технологию перехвата метода, чтобы перехватить все вызовы методов родительского класса.
Имитировать шаги генерации агента
Идеи:
Функция реализации: вернуть объект прокси через NewProxyInstance Proxy
1. Объявите часть исходного кода (агент динамического генерации)
2. Скомпилируйте исходный код (jdkcompilerapi) для создания новых классов (классы прокси)
3. Загрузите этот класс в память и генерируйте новый объект (объект прокси)
4. вернуть объект прокси -сервера
Улучшение динамической реализации прокси -сервера
Сначала мы получаем системный компилятор, проведем файловый диспетчер через компилятор, а затем получаем файл. Затем компилятор выполняет задачу компиляции. После завершения компиляции мы загружаем файл класса в загрузчик класса, получаем экземпляр с помощью метода конструктора, а затем вызовываем newInstance (), чтобы получить экземпляр объекта.
(1) Получить компилятор javacompilercompiler = toolprovider.getsystemjavacompiler ();
(2) файловый менеджер standardjavafilemanagerfilemgr = compiler.getstandardfilemanager (null, null, null);
(3) Получить файл iterableUnits = filemgr.getJavafileObjects (filename);
(4) Компиляция Компиляции задачи totaskt = compiler.gettask (null, filemgr, null, null, null, null, единицы);
(5) Загрузите в память
ClassLoadercl = classLoader.getSystemClassLoader ();
Classc = cl.loadclass ("com.imooc.proxy. $ Proxy0");
(6) Построить экземпляр через конструктор прокси -объекта
Constructorctr = c.getConstructor (infce);
ctr.newinstance (newcar ());
--------
Как упомянуто выше, внутренняя бизнес-логика жестко кодируется. Как реализовать настоящий динамический прокси и динамически обозначенную бизнес -логику?
1. Вам нужно создать процессор транзакций. Во -первых, вы создаете интерфейс, то есть InvocationHandler. Чтобы имитировать JDK, имя интерфейса такое же, как и название процессора транзакции JDK. Вы также пишете метод под названием Invoke (), который используется для представления определенного метода объекта для бизнес -обработки. Следовательно, вам нужно передать определенный объект и метод объекта в качестве параметров метода inoke (). Invoke (ObjectObj, MethodMethod), метод, используемый в качестве параметра для отражения Java, и этот пакет должен быть введен. Таким образом, интерфейс InvocationHandler завершен.
2. Создание классов реализации обработки транзакций, таких как TimerProxy, для реализации интерфейса vocalHandler, поэтому структура становится
- - - -
Вам нужно передать целевой объект. Если у вас нет параметров, вы не можете написать параметры. Создайте метод построения прокси -объекта и инициализируйте целевой объект.
3. В методе NewProxyInstance () класса прокси, в дополнение к использованию интерфейса целевого класса в качестве параметра, вам также необходимо передавать процессор транзакции vlocationHandler, а затем изменить жесткую часть объекта созданного экземпляра и использовать метод транзакционного процессора, чтобы заменить его. Сложность заключается в сплайсинге струн.
Суммировать
В нашем проекте Agent Pattern имеет свое практическое значение. Например, если мы хотим позвонить в класс в определенном пакете JAR, мы можем добавить некоторую специальную бизнес -логику перед вызовом этого класса. Этот метод также называется AOP-ориентированным программированием. (Добавьте дополнительные функции без изменения исходных функций.)
Выше приведено подробное объяснение кода Java Dynamic Proxy Proxy (шаблона дизайна) в этой статье, я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на другие связанные темы на этом сайте. Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!