Subject.java
public interface Subject {
public void rent();
public void hello(String str);
public void methodNotImpl();
}
ProxyGeneratorUtils.java // Чтобы сохранить файл класса прокси в локальном.
public class ProxyGeneratorUtils {
public static void writeProxyClassToHardDisk(String path) {
byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0", RealSubject.class.getInterfaces());
FileOutputStream out = null;
try {
out = new FileOutputStream(path);
out.write(classFile);
out.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Test
@Test
public void testGenerateProxyClass() {
ProxyGeneratorUtils.writeProxyClassToHardDisk("/Desktop/temp/$Proxy0.class";
}
}
Декомпилировать$ Proxy0.class использует какой-то инструмент и получает $ Proxy0.java
import com.AnotherExample.*;
import java.lang.reflect.*;
public final class $Proxy0 extends Proxy implements Subject
{
private static Method m1;
private static Method m4;
private static Method m5;
private static Method m2;
private static Method m3;
private static Method m0;
public $Proxy0(final InvocationHandler invocationHandler) {
super(invocationHandler);
}
public final boolean equals(final Object o) {
try {
return (boolean)super.h.invoke(this, $Proxy0.m1, new Object[] { o });
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
public final void rent() {
try {
super.h.invoke(this, $Proxy0.m4, null);//*****
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
public final void methodNotImpl() {
try {
super.h.invoke(this, $Proxy0.m5, null);
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
public final String toString() {
try {
return (String)super.h.invoke(this, $Proxy0.m2, null);
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
public final void hello(final String s) {
try {
super.h.invoke(this, $Proxy0.m3, new Object[] { s });
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
public final int hashCode() {
try {
return (int)super.h.invoke(this, $Proxy0.m0, null);
}
catch (Error | RuntimeException error) {
throw;
}
catch (Throwable t) {
throw new UndeclaredThrowableException(t);
}
}
static {
try {
$Proxy0.m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
$Proxy0.m4 = Class.forName("com.AnotherExample.Subject").getMethod("rent", (Class<?>[])new Class[0]);
$Proxy0.m5 = Class.forName("com.AnotherExample.Subject").getMethod("methodNotImpl", (Class<?>[])new Class[0]);
$Proxy0.m2 = Class.forName("java.lang.Object").getMethod("toString", (Class<?>[])new Class[0]);
$Proxy0.m3 = Class.forName("com.AnotherExample.Subject").getMethod("hello", Class.forName("java.lang.String"));
$Proxy0.m0 = Class.forName("java.lang.Object").getMethod("hashCode", (Class<?>[])new Class[0]);
}
catch (NoSuchMethodException ex) {
throw new NoSuchMethodError(ex.getMessage());
}
catch (ClassNotFoundException ex2) {
throw new NoClassDefFoundError(ex2.getMessage());
}
}
}
Client.java // Для справки
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client
{
public static void main(String[] args)
{
Subject realSubject = new RealSubject();
InvocationHandler handler = new DynamicProxy(realSubject);//handler own the realSubject's information
Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject
.getClass().getInterfaces(), handler);
System.out.println(subject.getClass().getName());
subject.rent();
subject.hello("world");
subject.methodNotImpl();
}
}
Благодаря этим шагам мы точно знаем, как работает прокси , Нетнезависимо от того, какая функция определена в интерфейсе, который мы назвали, $ proxy0 сначала вызовет функцию invoke super.h.invoke () {} ;
Мы могли бы передать информацию о методе интерфейса объекту InvocationHandler (который использовался для создания прокси).
Затем мы могли бы сделать что угодно (включая вызов функции интерфейса) в функцию super.h.invoke () {}.
Если мы хотим вызвать функцию realSubject, нам просто нужно использовать полиморфизм, передавая объект RealSubject через method.invoke (realSubject, args);
Пожалуйста, знайте, что это выполнено тольковызов функции интерфейса субъекта и прокси объекта, а не класса