Spring-8-JDK动态代理
2019-10-04 本文已影响0人
宠辱不惊的咸鱼
JDK动态代理分步使用步骤
- 通过实现InvocationHandler接口来自定义自己的InvocationHandler(在InvocationHandler初始化对象时绑定target)
public class HWInvocationHandler implements InvocationHandler {
private Object target;
public HWInvocationHandler (Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
System.out.println("-----插入前置通知代码-----");
Object re = method.invoke(target, args);
System.out.println("-----插入后置处理代码-----");
return rs;
}
}
- 通过Proxy.getProxyClass获得动态代理类的Class对象,参数:类加载器,接口列表
public void test() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
System.getProperties.put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
Class proxyClazz = Proxy.getProxyClass(IHello.class.getClassLoader(), new Class[]{ IHello.class });
Constructor constructor = proxyClazz.getConstructor(InvocationHandler.class);
IHello ihello = (IHello) constructor.newInstance(new HWInvocationHandler(new Hello()));
ihello.sayHello();
}
- 通过反射机制获得代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)
- 通过构造函数的newInstance获得代理对象,参数就是自定义的InvocationHandler
- 通过代理对象调用目标方法,代理对象与目标对象的同名方法中,执行其持有的InvocationHandler(这个对象是在Proxy中声明的属性,被代理类继承过来了)对象的invoke方法
- 说明
IHello // 接口
Hello // 业务实现类业务
public final class $Proxy0 extends Proxy implements IHello // 生成的代理类$Proxy0
public $Proxy0 (InvocationHandler paramInvocationHandler) {
super(paramInvocationHandler); //代理类的构造函数直接用父类Proxy的
}
protected Proxy (InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}
Proxy.newProxyInstance
- Proxy中,有一个封装的方法来一步到位的生成代理对象
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
IHello ihello = (IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(), new Class[] {IHello.class}, new InvocationHandler(new Hello()));
ihello.sayHello();
Spring里的代码流程
- 下面的JDK动态代理原理逻辑分析就以newProxyInstance来展开了,虽然和上面的分步式存在一些代码差别,但原理是一致的
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
- Proxy.newProxyInstance(classLoader, proxiedInterfaces, this)
- this就是JdkDynamicAopProxy本身
- Class<?> cl = getProxyClass0(loader, intfs);
- Proxy.getProxyClass0
- return proxyClassCache.get(loader, interfaces);
- Weakcache.get
- V value = supplier.get();
- WeakCache$Factory.get
- value = Objects.requireNonNull(valueFactory.apply(key, parameter));
- Proxy$ProxyClassFactory.apply
- byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
package com.sun.proxy;
import com.fjh.aop.ITarget;
import com.fjh.aop.ITarget2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy2 extends Proxy implements ITarget, ITarget2 {
private static Method m1;
private static Method m4;
private static Method m2;
private static Method m3;
private static Method m0;
public $Proxy2(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void target2() throws {
try {
super.h.invoke(this, m4, (Object[])null);
} 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);
}
}
public final void target() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (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("com.fjh.aop.ITarget2").getMethod("target2");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("com.fjh.aop.ITarget").getMethod("target");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}