Подробное объяснение динамического прокси JDK
В этой статье в основном представлены основные принципы динамического прокси JDK, чтобы каждый мог более глубоко понять прокси JDK, знать, что это такое. Понять истинный принцип динамического прокси JDK и его процесса его генерации. Давайте сначала возьмем простую демонстрацию.
JDK Proxy Helloworld
Пакет com.yao.proxy;/** * Создан Робин */Публичный интерфейс Helloworld {void sayshello ();} Пакет com.yao.proxy; импорт com.yao.helloworld;/** * Создан Робин */Общедоступный класс Helloworldimpl Recules Helloworld {public void sayhello () {System.out.print ("Hello World"); Пакет com.yao.proxy; импортировать java.lang.reflect.invocationHandler; импорт java.lang.reflect.method;/** * Создан Robin */public class myInvocationHandler. System.out.println ("Метод:"+ method.getName ()+ " Пакет com.yao.proxy; импорт com.yao.helloworld; import java.lang.reflect.constructor; импорт java.lang.reflect.invocationHandler; импорт java.lang.reflect.invocationTargexcept ] args) бросает nosuchmethodexception, allodalaccessexception, InvocationTargetException, instantiationException {// Есть два способа написать здесь. Class <?> ProxyClass = Proxy.getProxyClass (jdkproxytest.class.getClassloader (), helloworld.class); ewinstance (ih); // Следующий прокси, по сути, более простой способ написания. }}Запустите приведенный выше код, и будет реализован такой простой прокси JDK.
Процесс генерации агента
Причина, по которой мы каждый день называем JDK Dynamic Dynamic Proxy, заключается в том, что этот класс прокси -сервера генерируется JDK для нас во время выполнения. Прежде чем объяснить процесс генерации прокси, мы сначала добавляем параметр -desun.misc.proxygenerator.savegenedfiles = true для параметра запуска JVM. Я использовал Intellij Idea, и после того, как прокси -класс был сгенерирован, она была размещена непосредственно в корневом каталоге проекта , с конкретным именем пакета в качестве структуры каталогов.
Процесс генерации класса прокси в основном включает в себя две части:
Ввод метода GetProxyClass в классе прокси: вам нужно пройти в классе загрузчика и интерфейса
Затем вызовите метод GetProxyClass, и аннотация в нем очень ясна. Здесь ясно видно, что существует ограничение на количество интерфейсных интерфейсов, которые не могут превышать 65535. Конкретная информация инициализации ProxyClassCache заключается в следующем:
ProxyClassCache = new SleasdCache <> (new KeyFactory (), New ProxyClassFactory ());
Конкретная логика для создания класса прокси -класса создается с помощью метода Apply ProxyClassFactory.
Логика в ProxyClassFactory включает в себя логику создания имени пакета, вызов проксигенератора.
1. Логика имени пакета по умолчанию-com.sun.proxy.
2. После того, как имя пакета готово, прокси -код создается в соответствии с конкретным входящим интерфейсом через проксигенератор. В классе прокси все прокси -методы одинаковы, чтобы вызвать метод Invoke of Invocationhander.
3. Загрузите байт -код в JVM через пропущенный загрузчик класса: delineClass0 (Loader, Proxyname, ProxyClassFile, 0, proxyClassfile.length);.
Частный статический класс Proxyclassfactory Imprements Bifunction <ClassLoader, Class <?> [], класс <? >> {// Префикс для всех имен классов Proxy Private Static Final String ProxyClassmaprefix = "$ Proxy"; э -э -э -э -э -э -э -э -э -э -э -э Class <?> [] Интерфейсы) {Map <? ame (), false, загрузчик); (Interfaceclass! ПЛИКАНТА (Интерфейс. лицо так, чтобы * прокси -класс был определен в том же пакете * Все непубликованные прокси-интерфейсы находятся в том же пакете kg = (n == -1)? "": name.substring (0, n + 1)); proxypkg = pkg; . ";} / * * Выберите имя для генерации класса прокси. * / Long num = NextUniqueNumber.getandIncrement (); Yname, Interfaces, AccessFlags); proxyclase.length);Мы можем декомпилировать на основе байт -кода класса прокси, и мы можем получить следующие результаты.
Грубая структура агента включает в себя 4 части:
Package com.sun.proxy; импорт com.yao.helloworld; импорт java.lang.reflect.invocationHandler; импорт java.lang.reflect.method; импорт java.lang.reflect.proxy; import java.lang.Reflect. undeclareBrowableException Метод M3; public $ proxy0 (valyhandler var1) Throws {super (var1); LAREDTROWABLEEXCEPTE (var4); Throws {try {super.h.invoke (this, m3, (object []) null); } catch (Runtimeexception | erron var2) {throw var2; var3) {Выбросить новый UndeclaredThableException (var3); 3); Class.forname ("java.lang.object"). GetMethod ("equals", новый класс [] {class.forname ("java.lang.object")}); OD ("Tostring", новый класс [0]); Класс [0]);ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ:
1. ToString () HashCode () Ecoud () Метод вызова. Другие методы на объектах не будут следовать логике обработки прокси, но будут непосредственно следить за логикой метода на объекте, унаследованном прокси.
2. Когда интерфейс содержит равные и подводные методы хэшкода, он будет следовать логике обработчика вызова, как и обработка обычных методов интерфейса, и запустить логику метода на основе переписывания целевого объекта;
3. Интерфейс содержит дублирующие подписи метода, которые подлежат порядок, в котором проходит интерфейс.
Спасибо за чтение, я надеюсь, что это может помочь вам.