JDK动态代理
现象
实现类两方法
public class TargetServiceImpl implements TargetService {
@Override
public void a() {
System.out.println("a");
b();
System.out.println("-------------------------------------------------------");
}
@Override
public void b() {
System.out.println("b");
}
}
拦截部分
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("enter JDK method:"+method.getName()+"()");
if (method.getName() == "b") {
System.out.println("c");
}
return method.invoke(target, args); //调用原生方法
}
TargetService proxy = (TargetService) getProxy(new TargetServiceImpl());
proxy.a();
proxy.b();
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLzElaNFTWq10dRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL3gjZ1kTZ1UTYjJGNxIjNiRzY0QDMzkzNzMWYwIWZiNzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
也就是说a里的b方法没被拦截,因为内部的this是原始对象:[email protected]
源码分析
核心代码分析
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
{
final Class<?>[] intfs = interfaces.clone();
Class<?> cl = getProxyClass0(loader, intfs); // 获取代理类的Class对象
final Constructor<?> cons = cl.getConstructor(constructorParams);//根据参数获取构造函数
return cons.newInstance(new Object[]{h});//生成代理类的实例
}
getProxyClass0(loader, intfs); ->return proxyClassCache.get(loader, interfaces);
其中 proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
首先会在缓存中查到是否该类加载器已经加载过该代理类,如果找到则直接返回,否则使用 ProxyClassFactory来生成代理类
public V get(K key, P parameter) {
// 从缓存中获取supplier
while (true) {
if (supplier != null) {
// supplier might be a Factory or a CacheValue<V> instance
V value = supplier.get();
if (value != null) {
return value;
}
}
// else no supplier in cache
// or a supplier that returned null (could be a cleared CacheValue
// or a Factory that wasn't successful in installing the CacheValue)
使用 ProxyClassFactory来生成代理类
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
// prefix for all proxy class names
private static final String proxyClassNamePrefix = "$Proxy";
// next number to use for generation of unique proxy class names
private static final AtomicLong nextUniqueNumber = new AtomicLong();
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
/*
* Choose a name for the proxy class to generate.
*/
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
/*
* Generate the specified proxy class.
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass( //生成代理的字节码
proxyName, interfaces, accessFlags);
try {
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
字节码反编译
private static void createProxyClassFile(Class clazz){
String name = "Proxy"+clazz.getSimpleName();
byte[] data = ProxyGenerator.generateProxyClass(name,clazz.getInterfaces());
FileOutputStream out =null;
try {
out = new FileOutputStream(name+".class");
System.out.println((new File("proxyOutput")).getAbsolutePath());
out.write(data);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(null!=out) try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
将生成的字节码反编译
public final class ProxyTargetServiceImpl extends Proxy implements TargetService {
private static Method m1;
private static Method m3;
private static Method m4;
private static Method m2;
private static Method m0;
public ProxyTargetServiceImpl(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 b() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void a() 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 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"));
m3 = Class.forName("proxy.TargetService").getMethod("b");
m4 = Class.forName("proxy.TargetService").getMethod("a");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
JDK动态代理只会将实现的接口里的方法添加为代理方法。
super.h即InvocationHandler,然后调用它的Invoke方法即
this为代理,此处即ProxyTargetServiceImpl
m4 = Class.forName("proxy.TargetService").getMethod("a");
CGLIB动态代理
现象
增强逻辑
public static Object getProxy(Class<?> clazz) {
Enhancer enhancer = new Enhancer();
enhancer.setClassLoader(clazz.getClassLoader());
enhancer.setSuperclass(clazz); //增强类是被代理类的子类
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("enter cglib method:"+method.getName()+"()");
if (method.getName() == "b") {
System.out.println("c");
}
Object invokeResult = methodProxy.invokeSuper(o, objects);
return invokeResult;
}
});
return enhancer.create();
}
public class CglibTarget {
public void a() {
System.out.println("a");
b();
System.out.println("-------------------------------------------------------");
}
public void b() {
System.out.println("b");
}
}
CglibTarget proxy = (CglibTarget)getProxy(CglibTarget.class);
proxy.a();
proxy.b();
源码分析
Object invokeResult = methodProxy.invokeSuper(o, objects);
invoke进入实际的方法:这里不一样的是this是增强后的代理对象doTest.CglibTarget E n h a n c e r B y C G L I B EnhancerByCGLIB EnhancerByCGLIB[email protected]
字节码反编译
main函数中加入如下语句
public class CglibTarget$$EnhancerByCGLIB$$75dccf2e extends CglibTarget implements Factory {
var10000 = ReflectUtils.findMethods(new String[]{"b", "()V", "a", "()V"}, (var1 = Class.forName("doTest.CglibTarget")).getDeclaredMethods());
CGLIB$b$0$Method = var10000[0];
CGLIB$b$0$Proxy = MethodProxy.create(var1, var0, "()V", "b", "CGLIB$b$0");
CGLIB$a$1$Method = var10000[1];
CGLIB$a$1$Proxy = MethodProxy.create(var1, var0, "()V", "a", "CGLIB$a$1");
final void CGLIB$b$0() {
super.b();
}
public final void b() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
var10000.intercept(this, CGLIB$b$0$Method, CGLIB$emptyArgs, CGLIB$b$0$Proxy);
} else {
super.b();
}
}
final void CGLIB$a$1() {
super.a();
}
public final void a() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
var10000.intercept(this, CGLIB$a$1$Method, CGLIB$emptyArgs, CGLIB$a$1$Proxy);
} else {
super.a();
}
}