springAop 才用了2种动态代理机制,一个是cglib动态代理,一个是jdk动态代理。
今天通过一个例子来追踪一下jdk动态代理原理。
public interface NewsService {
public void add();
public void del();
}
public class NewsServiceImpl implements NewsService {
@Override
public void add() {
System.out.println("This is add service");
}
@Override
public void del() {
System.out.println("This is del service");
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyInvocatioHandler implements InvocationHandler {
private Object target;
public MyInvocatioHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("-----before-----");
Object result = method.invoke(target, args);
System.out.println("-----end-----");
return result;
}
// 生成代理对象
public Object getProxy() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class<?>[] interfaces = target.getClass().getInterfaces();
return Proxy.newProxyInstance(loader, interfaces, this);
}
}
public class ProxyTest {
public static void main(String[] args) {
NewsService service = new NewsServiceImpl();
MyInvocatioHandler handler = new MyInvocatioHandler(service);
NewsService serviceProxy = (NewsService) handler.getProxy();
serviceProxy.add();
serviceProxy.del();
}
控制台的结果是
—–before—–
This is add service
—–end—–
—–before—–
This is del service
—–end—–
下面我们就追一下代码
我们先看一下我们的代理对象是怎么生成的
Proxy.newProxyInstance(loader, interfaces, this);
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
.......
/*
* Look up or generate the designated proxy class.
* 查找或生成指定的代理类
*/
Class<?> cl = getProxyClass0(loader, interfaces);
final Constructor<?> cons = cl.getConstructor(constructorParams);
.....
final InvocationHandler ih = h;
.....
return newInstance(cons, ih);
.......
}
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
......
return proxyClassCache.get(loader, interfaces);
}
public V get(K key, P parameter) {
.......
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
......
这里的提到了apply(),是Proxy类的内部类ProxyClassFactory实现其接口的一个方法,具体实现如下:
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
.......
/*
* Generate the specified proxy class.
* 生成指定的代理类
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces);
try {
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
}
}
这个方法是生成代理类的字节数组,待会将在测试类里直接调用,看看代理类文件到底长什么样子。
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces);
这个方法根据类加载器,代理类名,代理类文件返回动态代理类
defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
看看我们生成的代理文件
public class ProxyTest {
public static void main(String[] args) {
NewsService service = new NewsServiceImpl();
generatorProxyFile(service);
}
public static void generatorProxyFile(NewsService service) {
byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy.1", service.getClass().getInterfaces());
FileOutputStream out = null;
try {
out = new FileOutputStream("$Proxy.1.class");
out.write(classFile);
out.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
为了看起来简洁一些我把异常处理删掉
public final class 2 extends Proxy
implements NewsService
{
private static Method m1;
private static Method m3;
private static Method m0;
private static Method m4;
private static Method m2;
public 2(InvocationHandler paramInvocationHandler) {
super(paramInvocationHandler);
}
public final boolean equals(Object paramObject) {
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
public final void add(){
this.h.invoke(this, m3, null);
return;
}
public final int hashCode(){
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
public final void del(){
this.h.invoke(this, m4, null);
return;
}
public final String toString() {
return (String)this.h.invoke(this, m2, null);
}
static
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m3 = Class.forName("test.NewsService").getMethod("add", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m4 = Class.forName("test.NewsService").getMethod("del", new Class[0]);
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
return;
}
这里我们看到了我们的add del 方法都变成了有h.invode(….);
h就是我们MyInvocatioHandler对象。
构造函数里传入了一个InvocationHandler类型的参数,
public 2(InvocationHandler paramInvocationHandler) {
super(paramInvocationHandler);
}
看到这里,我们就应该想到之前的一行代码:
return cons.newInstance(new Object[]{h});
所以执行代理对象的add方法 实际上执行的是MyInvocatioHandler.invoke(proxy,add,args);