代理有静态代理和动态代理
-
静态代理里分继承(extends)和聚合(接口)
(1) 继承的话就是通过super操作父类了。
(2) 聚合的话,就是在代理类里指定一个接口属性,为接口属性指定一个要被代理的对象,然后在该代理类里调用被代理的对象,对其前后进行增强。 -
动态代理市面上主流的技术有2种:jdk动态代理、cglib动态代理。像ASM、javac都不是主流的,虽然cglib得使用到ASM,但那属于太底层的了,没必要去学。
①jdk动态代理主要使用 Proxy.newProxyInstance (ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
第一个参数ClassLoader loader : 类加载器
第二个参数 Class<?>[] interfaces : 需要要实现的接口
第三个参数 InvocationHandler h : 所要增强或改变的方法的 逻辑代码
JDK动态代理需要的是需要实现的接口和invocationHandle这个增强的逻辑代码类
CGLIB动态代理需要的是父类和methodIntercepter这个增强的逻辑代码类
JDK的动态代理过程,就像是Proxy里固定写死了 InvocationHandler属性h,通过Proxy.newProxyInstance (ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)来传入,然后在代理对象的方法里就是调用父类Proxy里固定死的h的invoke方法(里边就可以执行被代理对象和自己添加的增强逻辑代码),而且invoke方法需要传入被代理的对象方法和参数什么的。所以下边所示的是JDK动态代理的反编译。
public final class $GameProxy extends Proxy implements Game{
private static Method m1;
private static Method m2;
private static Method m3;
private static Method m0;
public $GameProxy(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 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 paly() 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"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m3 = Class.forName("com.byzh.Game").getMethod("paly");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
②cglib动态代理
cglib的使用步骤
Enhancer enhancer = new Enhancer(); // 通过CGLIB动态代理获取代理对象的过程
enhancer.setSuperclass(XXXXXX); // 设置enhancer对象的父类
enhancer.setCallback(new MyMethodInterceptor());// 设置enhancer的回调对象(增强的逻辑代码)
XXXXX proxy= (XXXX)enhancer.create(); // 创建代理对象
proxy.xxxxx(); // 通过代理对象调用目标方法
cglib的代理过程,就像是在enhancer里固定写死了MethodInterceptor 属性,通过setCallback来设置MethodInterceptor ,然后在代理对象的方法里就是调用MethodInterceptor的固定方法(里边能调用父类的方法和添加自己的增强逻辑)就行了。