版权声明:转载原创博客请附上原文链接 https://blog.csdn.net/weixin_43495590/article/details/89156006
一:概述
代理模式分为静态代理与动态代理,动态代理相对于静态代理可以更加灵活进行处理,不需要逐个方法进行中转
。静态代理过于简单不在本文讨论范围,本文着重与讨论JDK自带的Proxy代理与Cglib代理应用实现
二:JDK动态代理
2.1 简单应用
- 被代理类实现接口,被代理类必须实现接口
- 必须实现接口是JDK动态代理一个弊端也是和Cglib主要的区别
- 实现接口作用在于Proxy进行组装时需要这个接口的Class对象
public interface PublicInterface {
void testMethod();
}
public class TrueImplement implements PublicInterface{
@Override
public void testMethod() {
System.out.println("真正处理实现");
}
}
- 实现InvocationHandler接口重写invoke()方法,方法中定义代理方法执行逻辑
- invoke()参数proxy代指代理对象、method代指代理方法、args代指方法参数
- Proxy类的newProxyInstance()根据类加载器、代理对象实现接口Class进行代理对象组装
- newProxyInstancee()第三个参数InvocationHandler对象用于Proxy对象组装时反射操作构造函数的实参
public class ProxyImplement implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入方法");
method.invoke(new TestImplement(),args);
System.out.println("结束方法");
return null;
}
public <T> T getProxy(){
return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
PublicInterface.class.getInterfaces(),
this);
}
}
public class Test {
public static void main(String[] args) {
ProxyImplement pi = new ProxyImplement();
PublicInterface proxy = pi.getProxy();
proxy.testMethod();
}
}
2.2 源码解析
newProxyInstance()作为入口查看,里面做的操作都是在获取到Proxy类Class对象后构造函数获取
、权限判断修改
、对象实例化
等操作
private static final Class<?>[] constructorParams =
{ InvocationHandler.class };
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
// 检查第三个参数InvocationHandler实例是否为空
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
// 获取proxy代理类
Class<?> cl = getProxyClass0(loader, intfs);
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
// 获取Proxy类构造函数
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
// 判断访问权限并允许访问
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
// 返回创建Proxy实例
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
再看newProxyInstance()中获取Proxy类的Class对象方法getProxyClass0(),这里面进行了两个操作。对接口长度限制
,调用WeakCache类get()
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
// 文件字节码中的固定规定不能超过65535字节
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// 给定接口如果存在将返回储存副本
// 如果不存在则使用ProxyClassFactory创建
return proxyClassCache.get(loader, interfaces);
}
截取get()中最重要一行代码,紧接着追入apply()查看。apply()位于Proxy类的内部类ProxyClassFactory
中
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {
Class<?> interfaceClass = null;
try {
//通过类加载器加载class到内存
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
if (interfaceClass != intf) {
throw new IllegalArgumentException(
intf + " is not visible from class loader");
}
//判断class是否接口
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
//没有重复定义的接口
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
}
//proxy Class所在包
String proxyPkg = null;
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
//判断非public类是否在同一包下
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
}
if (proxyPkg == null) {
// 等价于com.sun.proxy.
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
long num = nextUniqueNumber.getAndIncrement();
//proxyPkg == null时,等价于com.sun.proxy.$proxy0,num会根据动态代理类的数量增加
String proxyName = proxyPkg + proxyClassNamePrefix + num;
//得到生成的字节码
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
//本地方法调用
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
throw new IllegalArgumentException(e.toString());
}
}
2.3 反编译代理生成类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import com.zsl.TrueImplement;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class CustomProxy extends Proxy implements TrueImplement {
private static Method m1;
private static Method m8;
private static Method m2;
private static Method m6;
private static Method m5;
private static Method m3;
private static Method m7;
private static Method m9;
private static Method m0;
private static Method m4;
public CustomProxy(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 notify() throws {
try {
super.h.invoke(this, m8, (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 wait(long var1) throws InterruptedException {
try {
super.h.invoke(this, m6, new Object[]{var1});
} catch (RuntimeException | InterruptedException | Error var4) {
throw var4;
} catch (Throwable var5) {
throw new UndeclaredThrowableException(var5);
}
}
public final void wait(long var1, int var3) throws InterruptedException {
try {
super.h.invoke(this, m5, new Object[]{var1, var3});
} catch (RuntimeException | InterruptedException | Error var5) {
throw var5;
} catch (Throwable var6) {
throw new UndeclaredThrowableException(var6);
}
}
// 这个方法对invoke()的调用才是代理核心
public final void testMethod() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final Class getClass() throws {
try {
return (Class)super.h.invoke(this, m7, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void notifyAll() throws {
try {
super.h.invoke(this, m9, (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);
}
}
public final void wait() throws InterruptedException {
try {
super.h.invoke(this, m4, (Object[])null);
} catch (RuntimeException | InterruptedException | 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"));
m8 = Class.forName("com.zsl.TrueImplement").getMethod("notify");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m6 = Class.forName("com.zsl.TrueImplement").getMethod("wait", Long.TYPE);
m5 = Class.forName("com.zsl.TrueImplement").getMethod("wait", Long.TYPE, Integer.TYPE);
m3 = Class.forName("com.zsl.TrueImplement").getMethod("testMethod");
m7 = Class.forName("com.zsl.TrueImplement").getMethod("getClass");
m9 = Class.forName("com.zsl.TrueImplement").getMethod("notifyAll");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
m4 = Class.forName("com.zsl.TrueImplement").getMethod("wait");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
三:Cglib
3.1 简单应用
- 实现MethodInterceptor接口,重写intercept(),该方法类似于拦截实现
- 代理对象实例化依赖Enhancer类,setSuperClass()参数为被代理类Class对象,setCallback()指代调用interceptor()的类,create()创建代理对象
- 源码查看可以从create()作为入口开始,没看懂留待以后补充
public class CglibImplement implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("代理之前");
methodProxy.invokeSuper(o,args);
System.out.println("代理之后");
return null;
}
@SuppressWarnings("unchecked")
public <T> T getProxy(Class<T> clazz) {
Enhancer en = new Enhancer();
//进行代理
en.setSuperclass(clazz);
en.setCallback(this);
//生成代理实例
return (T)en.create();
}
}
public static void main(String[] args) {
PublicInterface ci = new CglibImplement().getProxy(TrueImplement.class);
ci.testMethod();
}
3.2 JDK与Cglib区别
- JDK依赖于接口实现
- Cglib依赖于继承实现
- JDK采用原生反射实现,代理类生成效率优于Cglib
- Cglib方法代理的处理效率上高于JDK