jdk的动态代理即使用反射来实现,具体由Proxy、InvocationHandler等类来实现的。
具体调用过程比较难理解,但是如果看到生成的代理类就不难理解了。
代码如下:
接口类:Calculator.java
实现类:CalculatorImpl.java
代理类:CalculatorProxy.java
测试代码:TestProxy.java
反编译proxy.class得到的java代码如下:
因此,调用proxy.add(2,3),实际上就是调用LogHandler的invoke方法
具体调用过程比较难理解,但是如果看到生成的代理类就不难理解了。
代码如下:
接口类:Calculator.java
package com.yangjianzhou.javaBasics;
/**
* Created by yangjianzhou on 16-5-8.
*/
public interface Calculator {
public int add(int operator1 , int operator2);
}
实现类:CalculatorImpl.java
package com.yangjianzhou.javaBasics;
/**
* Created by yangjianzhou on 16-5-8.
*/
public class CalculatorImpl implements Calculator {
@Override
public int add(int operator1, int operator2) {
System.out.println("operator1 + operator2 = " + (operator1 + operator2));
return operator1 + operator2;
}
}
代理类:CalculatorProxy.java
package com.yangjianzhou.javaBasics;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* Created by yangjianzhou on 16-5-8.
*/
public class CalculatorProxy {
public void executeProxy(){
Calculator calculator = new CalculatorImpl();
LogHandler logHandler = new LogHandler(calculator);
Calculator proxy = (Calculator) Proxy.newProxyInstance(calculator.getClass().getClassLoader() , calculator.getClass().getInterfaces(),logHandler);
proxy.add(2,3);
}
}
class LogHandler implements InvocationHandler{
Object obj ;
public LogHandler(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.doBefore();
Object object = method.invoke(obj , args);
this.doAfter();
return object;
}
public void doBefore(){
System.out.println("log before method");
}
public void doAfter(){
System.out.println("log after method");
}
}
测试代码:TestProxy.java
package com.yangjianzhou.javaBasics;
import sun.misc.ProxyGenerator;
import java.io.FileOutputStream;
/**
* Created by yangjianzhou on 16-5-8.
*/
public class TestProxy {
public static void main(String[] args) throws Exception {
CalculatorProxy calculatorProxy = new CalculatorProxy();
calculatorProxy.executeProxy();
byte[] classCode = ProxyGenerator.generateProxyClass("com.yangjianzhou.javaBasics.", new Class[]{Calculator.class});
FileOutputStream fileOutputStream = new FileOutputStream("/tmp/proxy.class");
fileOutputStream.write(classCode);
fileOutputStream.close();
}
}
反编译proxy.class得到的java代码如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.yangjianzhou.javaBasics;
import com.yangjianzhou.javaBasics.Calculator;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class extends Proxy implements Calculator {
private static Method m1;
private static Method m0;
private static Method m3;
private static Method m2;
public (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);
}
}
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 int add(int var1, int var2) throws {
try {
return ((Integer)super.h.invoke(this, m3, new Object[]{Integer.valueOf(var1), Integer.valueOf(var2)})).intValue();
} catch (RuntimeException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
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", new Class[]{Class.forName("java.lang.Object")});
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m3 = Class.forName("com.yangjianzhou.javaBasics.Calculator").getMethod("add", new Class[]{Integer.TYPE, Integer.TYPE});
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
因此,调用proxy.add(2,3),实际上就是调用LogHandler的invoke方法