Динамический прокси на самом деле представляет собой класс java.lang.reflect.Proxy, который динамически генерирует байт класса на основе всех указанных вами интерфейсов. Этот класс унаследует класс Proxy и реализует все указанные вами интерфейсы (массив интерфейсов, который вы передаете в параметре). ) ; Затем используйте указанный вами загрузчик классов для загрузки байта класса в систему и, наконец, сгенерируйте объект такого класса и инициализируйте некоторые значения объекта, такие как invoctionHandler, которые являются членами метода, соответствующими всем интерфейсам. . После инициализации объект возвращается вызывающему клиенту. Таким образом, клиент получает объект Proxy, реализующий все ваши интерфейсы. Пожалуйста, посмотрите пример анализа:
общедоступный интерфейс BusinessProcessor {
общественный недействительный процесс Business ();
}
@Override
общественный недействительный процессBusiness() {
System.out.println("Обработка бизнеса...");
}
}
импортировать java.lang.reflect.IndictionHandler;
импортировать java.lang.reflect.Method;
/**
*Категория «Бизнес-агентство»
* @author fanshadoop
*
*/
публичный класс BusinessProcessorHandler реализует InlocationHandler {
цель частного объекта = ноль;
BusinessProcessorHandler (цель объекта) {
this.target = цель;
}
Открытый вызов объекта (прокси-сервер объекта, метод метода, аргументы Object[])
бросает Throwable {
Система.out
.println("Вы можете сделать что-нибудь здесь, прежде чем обработать свой бизнес");
Результат объекта = метод.invoke(цель, args);
Система.out
.println("Вы можете что-то сделать здесь после обработки вашего дела");
вернуть результат;
}
}
импортировать java.lang.reflect.Field;
импортировать java.lang.reflect.Method;
импортировать java.lang.reflect.Modifier;
импортировать java.lang.reflect.Proxy;
тест публичного класса {
/**
* @param аргументы
*/
public static void main(String[] args) {
BusinessProcessorImpl bpimpl = новый BusinessProcessorImpl();
Обработчик BusinessProcessorHandler = новый BusinessProcessorHandler(bpimpl);
БизнесПроцессор bp = (БизнесПроцессор) Proxy.newProxyInstance(
bpimpl.getClass().getClassLoader(), bpimpl.getClass()
.getInterfaces(), обработчик);
бп.процессБизнес();
System.out.println(bp.getClass().getName());
printClassDefinition(bp.getClass());
}
public static String getModifier(int modifier) {
Строковый результат = "";
переключатель (модификатор) {
Модификатор случая.ЧАСТНЫЙ:
результат = "частный";
Модификатор случая.PUBLIC:
результат = "публичный";
Модификатор случая.ЗАЩИТА:
результат = "защищено";
Модификатор случая.АБСТРАКТ:
результат = «аннотация»;
Модификатор случая.FINAL:
результат = «окончательный»;
Модификатор случая.NATIVE:
результат = "родной";
Модификатор случая.СТАТИКА:
результат = "статический";
Модификатор случая.SYNCHRONIZED:
результат = "синхронизировано";
Модификатор случая.STRICT:
результат = "строгий";
Модификатор случая.TRANSIENT:
результат = "переходный процесс";
Модификатор случая.VOLATILE:
результат = "летучий";
Модификатор случая.ИНТЕРФЕЙС:
результат = "интерфейс";
}
вернуть результат;
}
public static void printClassDefinition(Class clz) {
Строка clzModifier = getModifier(clz.getModifiers());
if (clzModifier != null && !clzModifier.equals("")) {
clzModifier = clzModifier + " ";
}
Строка superClz = clz.getSuperclass().getName();
if (superClz != null && !superClz.equals("")) {
superClz = «расширяет» + superClz;
}
Интерфейсы класса [] = clz.getInterfaces();
Строка inters = "";
for (int i = 0; i <interfaces.length; i++) {
если (я == 0) {
inters += "реализует";
}
inters += интерфейсы[i].getName();
}
System.out.println(clzModifier + clz.getName() + " " + superClz + " "
+ интер);
System.out.println("{");
Field[] поля = clz.getDeclaredFields();
for (int i = 0; i <fields.length; i++) {
Модификатор строки = getModifier(fields[i].getModifiers());
if (модификатор != null && !modifier.equals("")) {
модификатор = модификатор + " ";
}
Строка fieldName = поля[i].getName();
Строка fieldType = поля[i].getType().getName();
System.out.println(" " + модификатор + fieldType + " " + fieldName
+ ";");
}
Система.out.println();
Метод [] методы = clz.getDeclaredMethods();
for (int i = 0; i <methods.length; i++) {
Метод метод = методы[i];
Модификатор строки = getModifier(method.getModifiers());
if (модификатор != null && !modifier.equals("")) {
модификатор = модификатор + " ";
}
Строка имя метода = метод.getName();
Класс returnClz = метод.getReturnType();
Строка retrunType = returnClz.getName();
Класс [] clzs = метод.getParameterTypes();
Строка paraList = "(";
for (int j = 0; j < clzs.length; j++) {
paraList += clzs[j].getName();
if (j != clzs.length - 1) {
paraList += ", ";
}
}
paraList += ")";
clzs = метод.getExceptionTypes();
Строковые исключения = "";
for (int j = 0; j < clzs.length; j++) {
если (j == 0) {
исключения += "выдает";
}
исключения += clzs[j].getName();
if (j != clzs.length - 1) {
исключения += ", ";
}
}
исключения += ";";
Строковый методPrototype = модификатор + retrunType + " " + имя метода
+ paraList + исключения;
System.out.println(" " + методПрототип);
}
System.out.println("}");
}
}
логическое равенство (java.lang.Object);
java.lang.String toString();
интервал хеш-кода();
недействительный процессБизнес();
}
Очевидно, что метод Proxy.newProxyInstance будет выполнять следующие действия:
1. Динамически сгенерируйте класс на основе переданных в интерфейсах второго параметра для реализации интерфейса в интерфейсах. В этом примере это методprocessBusiness интерфейса BusinessProcessor. Он наследует класс Proxy и переписывает три метода, такие как hashcode, toString и Equals. Конкретную реализацию см. в ProxyGenerator.generateProxyClass(...); В этом примере создается класс $Proxy0.
2. Загрузите вновь созданный класс в jvm с помощью первого переданного параметра classloder. Собираемся загрузить класс $Proxy0
3. Используйте третий параметр для вызова конструктора $Proxy0 (InvoctionHandler) $Proxy0 для создания объекта $Proxy0 и используйте параметр интерфейсов для обхода всех его методов интерфейса и создания объекта метода для инициализации нескольких переменных-членов метода объект.
4. Верните экземпляр $Proxy0 клиенту.
Сейчас все в порядке. Посмотрим, как клиент это настроит и станет понятно.
1. Клиент получает объект экземпляра $Proxy0. Поскольку $Proxy0 наследует BusinessProcessor, нет проблем с его преобразованием в BusinessProcessor.
БизнесПроцессор bp = (БизнесПроцессор)Прокси.newProxyInstance(....);
2. bp.processBusiness();
На самом деле вызывается $Proxy0.processBusiness(), тогда реализация $Proxy0.processBusiness() заключается в вызове метода вызова через InlocationHandler!