接口
public interface Task {
void doSomething(String things);
String makeSomething(String seed);
}
实现类
public class TaskImpl implements Task {
@Override
public void doSomething(String things) {
System.out.println("I'm doing it : " + things);
}
@Override
public String makeSomething(String seed) {
return seed + "--" + seed;
}
}
InvocationHandler
public class TaskInvocationHandler implements InvocationHandler {
/**
* 代理对象
*/
private Object obj;
public TaskInvocationHandler(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
try{
System.out.println("You are calling : " + method.getName());
result = method.invoke(obj, args);
} catch (InvocationTargetException e) {
throw e;
} catch (Exception e) {
throw e;
}
return result;
}
}
动态代理工厂
public class TaskInvocationHandlerFactory {
public static Object newInstance(Object obj, Class clazz, InvocationHandler invocationHandler) {
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
new Class>[]{clazz}, invocationHandler);
}
}
测试代码
public class App {
public static void main(String[] args) {
//查看生成的代理类
//项目目录:E:\workspace\idea\snDemo\com\sun\proxy\$Proxy0.class
//System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
//$Proxy0.class ----> $Proxy0.txt
TaskImpl task = new TaskImpl();
Task taskProxy = (Task) TaskInvocationHandlerFactory.newInstance(task, Task.class, new TaskInvocationHandler(task));
taskProxy.doSomething("WTF");
String result = taskProxy.makeSomething("test");
System.out.println(result);
}
}
查看生成的代理类
项目目录:E:\workspace\idea\snDemo\com\sun\proxy\$Proxy0.class
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
代理类代码
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy0 extends Proxy implements Task {
private static Method m1;
private static Method m4;
private static Method m3;
private static Method m0;
private static Method m2;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return ((Boolean)super.h.invoke(this, m1, new Object[]{var1})).booleanValue();
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
//实际调用的是InvocationHandler的invoke方法
public final String makeSomething(String var1) throws {
try {
return (String)super.h.invoke(this, m4, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
//实际调用的是InvocationHandler的invoke方法
public final void doSomething(String var1) throws {
try {
super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final int hashCode() throws {
try {
return ((Integer)super.h.invoke(this, m0, (Object[])null)).intValue();
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
//反射获取方法
m4 = Class.forName("cn.suning.invocation.Task").getMethod("makeSomething", Class.forName("java.lang.String"));
m3 = Class.forName("cn.suning.invocation.Task").getMethod("doSomething", Class.forName("java.lang.String"));
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
m2 = Class.forName("java.lang.Object").getMethod("toString");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
原理
taskProxy的类型是 $Proxy0,taskProxy.doSomething 方法相当于调用 $Proxy0 类中的 doSomething 方法
//实际调用的是InvocationHandler的invoke方法
public final void doSomething(String var1) throws {
try {
super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
而 super.h.invoke 相当于调用TaskInvocationHandler类中的invoke的方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
try{
System.out.println("You are calling : " + method.getName());
//被代理方法调用
result = method.invoke(obj, args);
} catch (InvocationTargetException e) {
throw e;
} catch (Exception e) {
throw e;
}
return result;
}
TaskInvocationHandler 怎么传递给 $Proxy0 的呢
$Proxy0 继承 Proxy ,Proxy 中有变量 InvocationHandler h
public class Proxy implements java.io.Serializable {
private static final long serialVersionUID = -2222568056686623797L;
...............此处省略部分代码..................
* the invocation handler for this proxy instance.
* @serial
*/
protected InvocationHandler h;
}
然后通过 TaskInvocationHandlerFactory 的 newInstance 方法传递
public class TaskInvocationHandlerFactory {
public static Object newInstance(Object obj, Class clazz, InvocationHandler invocationHandler) {
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
new Class>[]{clazz}, invocationHandler);
}
}