java的动态代理底层解析(java的动态代理底层解析怎么做)

  本篇文章为你整理了java的动态代理底层解析(java的动态代理底层解析怎么做)的详细内容,包含有java的动态代理底层解析怎么写 java的动态代理底层解析怎么做 java动态代理底层原理 java动态代理 java的动态代理底层解析,希望能帮助你了解 java的动态代理底层解析。

  1.说明

   代理模式的解释:为其他对象提供一种代理以控制对这个对象的访问,增强一个类中的某个方法,对程序进行扩展。

  2.类型:

   CGLib动态代理和JDK动态代理

  3.使用介绍

   (1)CGLib动态代理的使用

   使用示例:

   1、针对代理类的示例

  

//构建代理对象

 

  public class TestObject {

   public void test(){

   System.out.println("test");

   public void test1(){

   System.out.println("test1");

  //构建方法拦截器

  public class MyMethodInterceptor implements MethodInterceptor {
//Object为由CGLib生成的代理类实例;Method为上文中实体类所调用的被代理的方法引用;Object[]为参数值列表;MethodProxy 为生成的代理类对方法的代理引用

   @Override

   public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

   System.out.println("before..");

   Object result = methodProxy.invokeSuper(o,objects);

   System.out.println("after..");

   return result;

  //生成代理步骤

  public static void main(String[] args) {

   Enhancer enhancer = new Enhancer(); //构造出加强器对象

   enhancer.setSuperclass(TestObject.class); //将代理类设置进去

   enhancer.setCallback(new MyMethodInterceptor());

   TestObject testObject= (TestObject)enhancer.create();

   testObject.test();

  }

 

   2、针对代理接口的示例

  

public interface UserInterface {

 

   public void test();

   public void test1();

  public class User implements UserInterface {

   @Override

   public void test() {

   System.out.println("test");

   @Override

   public void test1() {

   System.out.println("test1");

  public class MyInterfaceMyMethodInterceptor implements MethodInterceptor {

   Object object;

   public MyInterfaceMyMethodInterceptor(Object object) {

   this.object = object;

   @Override

   public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

   System.out.println("before..");

   Object result = methodProxy.invoke(object,objects);

   System.out.println("after..");

   return result;

  public static void main(final String[] args) {

   Enhancer enhancer = new Enhancer();

   enhancer.setSuperclass(UserInterface.class);

   enhancer.setCallback(new MyInterfaceMyMethodInterceptor(new User()));

   UserInterface userInterface = (UserInterface) enhancer.create();

   userInterface.test();

  }

 

  

   (2)JDK动态代理的使用

  

public interface UserInterface {

 

   public void test();

   public void test1();

  public class User implements UserInterface {

   @Override

   public void test() {

   System.out.println("test");

   @Override

   public void test1() {

   System.out.println("test1");

  public class MyInvocationHandler implements InvocationHandler {

   Object target;

   public MyInvocationHandler(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("after..");

   return result;

  public static void main(String[] args) {

   System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

   MyInvocationHandler myInvocationHandler = new MyInvocationHandler(new User());

   UserInterface userInterface = (UserInterface) Proxy.newProxyInstance(JDKDemo.class.getClassLoader(), new Class[]{UserInterface.class}, myInvocationHandler);

   userInterface.test();

  }

 

  

  

  4.底层分析(通过JVM添加参数-Dcglib.debugLocation=D:\IdeaProjects\cglib\cglib\target\classes【这个便是代理对象的存储路径】)

   代理类的class类(依据文件TestObject$$EnhancerByCGLIB$$783a36a0.class)

   (1)代码展示

  

//继承了代理类

 

  public class TestObject$$EnhancerByCGLIB$$783a36a0 extends TestObject implements Factory {

   private boolean CGLIB$BOUND;

   public static Object CGLIB$FACTORY_DATA;

   private static final ThreadLocal CGLIB$THREAD_CALLBACKS;

   private static final Callback[] CGLIB$STATIC_CALLBACKS;

   private MethodInterceptor CGLIB$CALLBACK_0; //这个值一开始是空的(没有给它赋值)

   private static Object CGLIB$CALLBACK_FILTER;

   private static final Method CGLIB$test$0$Method;

   private static final MethodProxy CGLIB$test$0$Proxy;

   private static final Object[] CGLIB$emptyArgs;

   private static final Method CGLIB$test1$1$Method;

   private static final MethodProxy CGLIB$test1$1$Proxy;

   private static final Method CGLIB$equals$2$Method;

   private static final MethodProxy CGLIB$equals$2$Proxy;

   private static final Method CGLIB$toString$3$Method;

   private static final MethodProxy CGLIB$toString$3$Proxy;

   private static final Method CGLIB$hashCode$4$Method;

   private static final MethodProxy CGLIB$hashCode$4$Proxy;

   private static final Method CGLIB$clone$5$Method;

   private static final MethodProxy CGLIB$clone$5$Proxy;

   static void CGLIB$STATICHOOK1() {

   CGLIB$THREAD_CALLBACKS = new ThreadLocal();

   CGLIB$emptyArgs = new Object[0];

   Class var0 = Class.forName("com.xiangxue.jack.aop.daili.TestObject$$EnhancerByCGLIB$$783a36a0");

   Class var1;

   //从目标类中拿出对应的方法构建成方法对象

   Method[] var10000 = ReflectUtils.findMethods(new String[]{"test", "()V", "test1", "()V"}, (var1 = Class.forName("com.xiangxue.jack.aop.daili.TestObject")).getDeclaredMethods());

   CGLIB$test$0$Method = var10000[0];

   //针对方法对象构建出代理对象

   CGLIB$test$0$Proxy = MethodProxy.create(var1, var0, "()V", "test", "CGLIB$test$0");

   CGLIB$test1$1$Method = var10000[1];

   CGLIB$test1$1$Proxy = MethodProxy.create(var1, var0, "()V", "test1", "CGLIB$test1$1");

   var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());

   CGLIB$equals$2$Method = var10000[0];

   CGLIB$equals$2$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");

   CGLIB$toString$3$Method = var10000[1];

   CGLIB$toString$3$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");

   CGLIB$hashCode$4$Method = var10000[2];

   CGLIB$hashCode$4$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$4");

   CGLIB$clone$5$Method = var10000[3];

   CGLIB$clone$5$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");

   //去执行父类的test()方法

   final void CGLIB$test$0() {

   super.test();

   //重写了父类的test()方法

   public final void test() {

   MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;

   if (var10000 == null) {

   CGLIB$BIND_CALLBACKS(this); //给 CGLIB$CALLBACK_0 属性赋值

   var10000 = this.CGLIB$CALLBACK_0;

   if (var10000 != null) {

   //四个参数分别为(当前的代理对象,方法,参数,未知)

   var10000.intercept(this, CGLIB$test$0$Method, CGLIB$emptyArgs, CGLIB$test$0$Proxy);

   } else {

   super.test();

   final void CGLIB$test1$1() {

   super.test1();

   public final void test1() {

   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$test1$1$Method, CGLIB$emptyArgs, CGLIB$test1$1$Proxy);

   } else {

   super.test1();

   final boolean CGLIB$equals$2(Object var1) {

   return super.equals(var1);

   public final boolean equals(Object var1) {

   MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;

   if (var10000 == null) {

   CGLIB$BIND_CALLBACKS(this);

   var10000 = this.CGLIB$CALLBACK_0;

   if (var10000 != null) {

   Object var2 = var10000.intercept(this, CGLIB$equals$2$Method, new Object[]{var1}, CGLIB$equals$2$Proxy);

   return var2 == null ? false : (Boolean)var2;

   } else {

   return super.equals(var1);

   final String CGLIB$toString$3() {

   return super.toString();

   public final String toString() {

   MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;

   if (var10000 == null) {

   CGLIB$BIND_CALLBACKS(this);

   var10000 = this.CGLIB$CALLBACK_0;

   return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy) : super.toString();

   final int CGLIB$hashCode$4() {

   return super.hashCode();

   public final int hashCode() {

   MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;

   if (var10000 == null) {

   CGLIB$BIND_CALLBACKS(this);

   var10000 = this.CGLIB$CALLBACK_0;

   if (var10000 != null) {

   Object var1 = var10000.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);

   return var1 == null ? 0 : ((Number)var1).intValue();

   } else {

   return super.hashCode();

   final Object CGLIB$clone$5() throws CloneNotSupportedException {

   return super.clone();

   protected final Object clone() throws CloneNotSupportedException {

   MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;

   if (var10000 == null) {

   CGLIB$BIND_CALLBACKS(this);

   var10000 = this.CGLIB$CALLBACK_0;

   return var10000 != null ? var10000.intercept(this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy) : super.clone();

   public static MethodProxy CGLIB$findMethodProxy(Signature var0) {

   String var10000 = var0.toString();

   switch(var10000.hashCode()) {

   case -1422510685:

   if (var10000.equals("test()V")) {

   return CGLIB$test$0$Proxy;

   break;

   case -1147892426:

   if (var10000.equals("test1()V")) {

   return CGLIB$test1$1$Proxy;

   break;

   case -508378822:

   if (var10000.equals("clone()Ljava/lang/Object;")) {

   return CGLIB$clone$5$Proxy;

   break;

   case 1826985398:

   if (var10000.equals("equals(Ljava/lang/Object;)Z")) {

   return CGLIB$equals$2$Proxy;

   break;

   case 1913648695:

   if (var10000.equals("toString()Ljava/lang/String;")) {

   return CGLIB$toString$3$Proxy;

   break;

   case 1984935277:

   if (var10000.equals("hashCode()I")) {

   return CGLIB$hashCode$4$Proxy;

   return null;

   public TestObject$$EnhancerByCGLIB$$783a36a0() {

   CGLIB$BIND_CALLBACKS(this);

   public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {

   CGLIB$THREAD_CALLBACKS.set(var0);

   public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {

   CGLIB$STATIC_CALLBACKS = var0;

   private static final void CGLIB$BIND_CALLBACKS(Object var0) {

   TestObject$$EnhancerByCGLIB$$783a36a0 var1 = (TestObject$$EnhancerByCGLIB$$783a36a0)var0;

   if (!var1.CGLIB$BOUND) { //一开始为false,布尔值的默认值

   var1.CGLIB$BOUND = true;

   Object var10000 = CGLIB$THREAD_CALLBACKS.get(); //从当前线程的ThreadLocal中获取

   if (var10000 == null) {

   var10000 = CGLIB$STATIC_CALLBACKS; //拦截器数组存储的地方

   if (var10000 == null) {

   return;

   var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0]; //取出数组第一位元素赋值过去

   public Object newInstance(Callback[] var1) {

   CGLIB$SET_THREAD_CALLBACKS(var1);

   TestObject$$EnhancerByCGLIB$$783a36a0 var10000 = new TestObject$$EnhancerByCGLIB$$783a36a0();

   CGLIB$SET_THREAD_CALLBACKS((Callback[])null);

   return var10000;

   public Object newInstance(Callback var1) {

   CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});

   TestObject$$EnhancerByCGLIB$$783a36a0 var10000 = new TestObject$$EnhancerByCGLIB$$783a36a0();

   CGLIB$SET_THREAD_CALLBACKS((Callback[])null);

   return var10000;

   public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {

   CGLIB$SET_THREAD_CALLBACKS(var3);

   TestObject$$EnhancerByCGLIB$$783a36a0 var10000 = new TestObject$$EnhancerByCGLIB$$783a36a0;

   switch(var1.length) {

   case 0:

   var10000. init ();

   CGLIB$SET_THREAD_CALLBACKS((Callback[])null);

   return var10000;

   default:

   throw new IllegalArgumentException("Constructor not found");

   public Callback getCallback(int var1) {

   CGLIB$BIND_CALLBACKS(this);

   MethodInterceptor var10000;

   switch(var1) {

   case 0:

   var10000 = this.CGLIB$CALLBACK_0;

   break;

   default:

   var10000 = null;

   return var10000;

   public void setCallback(int var1, Callback var2) {

   switch(var1) {

   case 0:

   this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;

   default:

   public Callback[] getCallbacks() {

   CGLIB$BIND_CALLBACKS(this);

   return new Callback[]{this.CGLIB$CALLBACK_0};

   public void setCallbacks(Callback[] var1) {

   this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];

   static {

   CGLIB$STATICHOOK1();

  }

 

  

   (2)调用流程说明

   当代理对象被调用的时候【假设为test()方法】

  

public final void test() {

 

   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$test$0$Method, CGLIB$emptyArgs, CGLIB$test$0$Proxy);

   } else {

   super.test();

  }

 

   CGLIB$CALLBACK_0该属性一开始是没有值的(因为初始化过程没有赋值的步骤),而获取值得步骤在于CGLIB$BIND_CALLBACKS(this);这一步。

  

private static final void CGLIB$BIND_CALLBACKS(Object var0) {

 

   TestObject$$EnhancerByCGLIB$$783a36a0 var1 = (TestObject$$EnhancerByCGLIB$$783a36a0)var0;

   if (!var1.CGLIB$BOUND) {

   var1.CGLIB$BOUND = true;

   Object var10000 = CGLIB$THREAD_CALLBACKS.get();

   if (var10000 == null) {

   var10000 = CGLIB$STATIC_CALLBACKS;

   if (var10000 == null) {

   return;

   var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];

  }

 

   这里面var1明显是指类本身,故CGLIB$BOUND会发现是布尔值类型,默认是false。而CGLIB$THREAD_CALLBACKS在静态代码块中被赋予了ThreadLocal,所以是打算从当前线程的ThreadLocal中获取。而CGLIB$STATIC_CALLBACKS类属性值中存放拦截方法数组的地方。然后返回数组的第一个元素过去。(1.这里有个问题ThreadLocal是什么时候被赋值的?)

  

   (3)问题汇总
 

   1.这里有个问题ThreadLocal是什么时候被赋值的?

   是在 CGLIB$SET_THREAD_CALLBACKS 这个方法中被赋值的,CGLIB$SET_THREAD_CALLBACKS这个方法又是在newInstance方法【生成代理对象的方法】中被执行。

   2.test()⽅法内会去调⽤所设置的Callbacks中的intercept(),相当于执⾏增强逻辑,如果没有Callbacks,则会执⾏super.test(),那么我们⾃然能想到,如果不设置Callbacks,那是不是就能正常执⾏呢?(是不能正常执行的)

  
异常出现在:createHelper()方法#preValidate()#CallbackInfo.determineTypes(callbacks, false);

   会报java.lang.IllegalStateException: Callback is null

  
createHelper()方法#preValidate()#CallbackInfo.determineTypes(callbacks, false);

   会报java.lang.NullPointerException

  

   (4)分析说明

  
动态代理类持有MethodInterceptor

  动态代理类会重写父类的非 final、private 方法【 如test() 】,也会构建自己的方法(cglib 方法),构建方式:CGLIB”+“$父类方法名$【 如CGLIB$test$0】。

  cglib 方法的方法体:super.方法名,直接调用父类;重写方法:它会调用拦截器中的intercept()方法。

  methodProxy.invokeSuper()方法会调用动态代理类中的 cglib 方法;methodProxy.invoke()方法会调用动态代理类中的重写方法

  
5.JDK动态代理源码分析(还未写全,待续)

   (1)Proxy.newProxyInstance(ClassLoader loader,Class ? [] interfaces,InvocationHandler h)

  

@CallerSensitive

 

  public static Object newProxyInstance(ClassLoader loader, Class ? [] interfaces, InvocationHandler h) throws IllegalArgumentException {

   Objects.requireNonNull(h);

   final Class ? [] intfs = interfaces.clone();

   final SecurityManager sm = System.getSecurityManager();

   if (sm != null) {

   checkProxyAccess(Reflection.getCallerClass(), loader, intfs);

   //去拿到代理类

   Class ? cl = getProxyClass0(loader, intfs);

   try {

   if (sm != null) {

   checkNewProxyPermission(Reflection.getCallerClass(), cl);

   //拿到代理类的构造方法

   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;

   //然后把拦截器传给构造方法

   return cons.newInstance(new Object[]{h});

   } catch (IllegalAccessExceptionInstantiationException e) {..} catch (InvocationTargetException e) {...} catch (NoSuchMethodException e) {... }

  }

 

  

  6.CGLib源码分析

   (1)Enhancer.create()

  

public Object create() {

 

   classOnly = false;

   argumentTypes = null;

   //执行创建

   return createHelper();

  }

 

  

   (2)Enhancer.createHelper()

  

private Object createHelper() {

 

   //校验callbackTypes,filter是否为空,已经为空的处理

   preValidate();

   // 通过newInstance方法生成了一个EnhancerKey代理对象,该代理对象里面保存了用户所设置的代理信息

   Object key = KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,

   ReflectUtils.getNames(interfaces),

   filter == ALL_ZERO ? null : new WeakCacheKey CallbackFilter (filter),

   callbackTypes,

   useFactory,

   interceptDuringConstruction,

   serialVersionUID);

   //设置当前Enhancer的代理类的key标识

   this.currentKey = key;

   // 调用父类AbstractClassGenerator的方法去创建代理对象

   Object result = super.create(key);

   return result;

  }

 

  

   (3)AbstractClassGenerator.create(Object key)

  

protected Object create(Object key) {

 

   try {

   ClassLoader loader = getClassLoader();

   Map ClassLoader, ClassLoaderData cache = CACHE;

   ClassLoaderData data = cache.get(loader);

   if (data == null) {

   synchronized (AbstractClassGenerator.class) {

   cache = CACHE;

   data = cache.get(loader);

   if (data == null) {

   Map ClassLoader, ClassLoaderData newCache = new WeakHashMap ClassLoader, ClassLoaderData (cache);

   // 构造方法中会生成一个生成代理类的lambda表达式

   data = new ClassLoaderData(loader);

   newCache.put(loader, data);

   CACHE = newCache;

   this.key = key;

   // 利用ClassLoaderData拿到代理类,ClassLoaderData中有一个generatedClasses用来缓存生成好的代理类

   // this就是Enhancer

   Object obj = data.get(this, getUseCache());

   if (obj instanceof Class) {

   // 调用代理类的构造方法生成一个代理对象

   return firstInstance((Class) obj);

   return nextInstance(obj);

   } catch (RuntimeException e) {...} catch (Error e) {...} catch (Exception e) {...}

  }

 

  

   (4)Enhancer.firstInstance((Class) obj) 与Enhancer.createUsingReflection(type)

  

protected Object firstInstance(Class type) throws Exception {

 

   if (classOnly) {

   return type;

   } else {

   return createUsingReflection(type);

  private Object createUsingReflection(Class type) {

   // 设置callbacks到代理类中

   setThreadCallbacks(type, callbacks);

   try{

   if (argumentTypes != null) {

   //根据代理类创建代理对象

   return ReflectUtils.newInstance(type, argumentTypes, arguments);

   } else {

   return ReflectUtils.newInstance(type);

   }finally{

   setThreadCallbacks(type, null);

  private static void setThreadCallbacks(Class type, Callback[] callbacks) {

   //private static final String SET_THREAD_CALLBACKS_NAME = "CGLIB$SET_THREAD_CALLBACKS";

   //这里便是调用将callbacks设置进入ThreadLocal里面

   //也就是利用反射区执行

   setCallbacksHelper(type, callbacks, SET_THREAD_CALLBACKS_NAME);

  }

 

  

   (5)ClassLoaderData.get(this, getUseCache())

  

public Object get(AbstractClassGenerator gen, boolean useCache) {

 

   if (!useCache) {//也就是enhancer.setUseCache(false);会起到作用的地方,

   // gen是Enhancer, ClassLoaderData.this中存储了EnhancerKey代理对象

   return gen.generate(ClassLoaderData.this);

   } else {//这里使用到缓存useCache=true

   Object cachedValue = generatedClasses.get(gen);

   return gen.unwrapCachedValue(cachedValue);

  //Enhancer.generate

  protected Class generate(ClassLoaderData data) {

   validate();

   //类的名字(可参考文件的名字)

   if (superclass != null) {

   setNamePrefix(superclass.getName());

   } else if (interfaces != null) {

   setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());

   //AbstractClassGenerator.generate

   return super.generate(data);

  //AbstractClassGenerator.generate

  protected Class generate(ClassLoaderData data) {

   Class gen;

   Object save = CURRENT.get();

   CURRENT.set(this);

   try {

   ClassLoader classLoader = data.getClassLoader();

   if (classLoader == null) { throw ex..;}

   synchronized (classLoader) {

   String name = generateClassName(data.getUniqueNamePredicate());

   data.reserveName(name);

   this.setClassName(name);

   if (attemptLoad) {

   try {

   gen = classLoader.loadClass(getClassName());

   return gen;

   } catch (ClassNotFoundException e) {..}

   // this就是Enhancer,主要是在这个方法里面利用ASM技术,生成代理类里面的东西

   byte[] b = strategy.generate(this);

   String className = ClassNameReader.getClassName(new ClassReader(b));

   ProtectionDomain protectionDomain = getProtectionDomain();

   synchronized (classLoader) { // just in case

   if (protectionDomain == null) {

   gen = ReflectUtils.defineClass(className, b, classLoader);

   } else {

   gen = ReflectUtils.defineClass(className, b, classLoader, protectionDomain);

   return gen;

   } catch (RuntimeException e) {..} catch (Error e) {..} catch (Exception e) {..} finally {

   CURRENT.set(save);

  //代码generatedClasses.get(gen)进入

  public V get(K key) {

   // 这里得到就是EnhancerKey的代理对象

   final KK cacheKey = keyMapper.apply(key);

   Object v = map.get(cacheKey);

   if (v != null !(v instanceof FutureTask)) {

   return (V) v;

   // 传进去的key为Enhancer对象,cacheKey为EnhancerKey的代理对象,表示所设置的代理信息

   return createEntry(key, cacheKey, v);

  
public V call() throws Exception {

   // 这里就会去创建代理类了,实际上也是调用gen.generate(ClassLoaderData.this);

   return loader.apply(key);

   Object prevTask = map.putIfAbsent(cacheKey, task);

   if (prevTask == null) {

   // creator does the load

   creator = true;

   task.run();

   } else if (prevTask instanceof FutureTask) {

   task = (FutureTask V ) prevTask;

   } else {

   return (V) prevTask;

   V result;

   try {

   result = task.get();

   } catch (InterruptedException e) {...} catch (ExecutionException e) {...}

   if (creator) {

   // 代理类创建完之后会进行缓存

   map.put(cacheKey, result);

   return result;

  }

 

  

  7.MethodProxy源码分析

   代码展示

  

public class UserService {

 

   public void test(){

   System.out.println("test");

  public static void main(String[] args) {

   final UserService target = new UserService();

   Enhancer enhancer = new Enhancer();

   enhancer.setUseCache(false);

   enhancer.setSuperclass(UserService.class);

   enhancer.setCallback(new MethodInterceptor() {

   @Override

   public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

   //为什么会存在有些报错有些不报错的问题?

   if (method.getName().equals("test")) {

   System.out.println("before...");

   methodProxy.invoke(o, objects); //报栈溢出错误

   methodProxy.invoke(target, objects);

   methodProxy.invokeSuper(o, objects);

   methodProxy.invokeSuper(target, objects); //报调⽤invokerSuper只能传⼊代理对象的错误

   System.out.println("after...");

   return null;

   return method.invoke(target, objects);

   UserService userService = (UserService) enhancer.create();

   userService.test();

  }

 

   代码说明

   在使用过程,我们常常遇到methodProxy上的方法使用问题,然而根本不知道为什么会这样。(虽然也不怎么会这样用)

   进行分析

   (1)MethodProxy是什么时候创建出来的?

   从上面的字节码文件可以看到是在静态方法CGLIB$STATICHOOK1()中生成的。

   源代码为(MethodProxy类#create方法)

  

create(Class c1, Class c2, String desc, String name1, String name2) {

 

   // c1是TestObject

   // c2是TestObject代理类[TestObject$$EnhancerByCGLIB$$783a36a0]

   // desc被代理方法的返回值类型

   // name1是被代理方法名比如test

   // name2是代理类中的CGLIB$test$0方法,会调用super.test()

   MethodProxy proxy = new MethodProxy();

   proxy.sig1 = new Signature(name1, desc); // 被代理方法签名,也就是代表void test()

   proxy.sig2 = new Signature(name2, desc); // 代理方法签名,也就是void CGLIB$test$0()

   proxy.createInfo = new CreateInfo(c1, c2); // CreateInfo中表示的就是被代理类和代理类的信息

   return proxy;

  }

 

  

   (2)MethodProxy的invoke方法与invokeSuper方法的区别?

   先上代码:

  

public Object invoke(Object obj, Object[] args) throws Throwable {

 

   try {

   init();

   FastClassInfo fci = fastClassInfo;

   // f1表示被代理类的FastClass代理类,i1表示被代理方法的下标,这里就是去执行test()方法,具体执行的是哪个对象就看obj

   return fci.f1.invoke(fci.i1, obj, args);

   } catch (InvocationTargetException e) {

   throw e.getTargetException();

   } catch (IllegalArgumentException e) {

   if (fastClassInfo.i1 0)

   throw new IllegalArgumentException("Protected method: " + sig1);

   throw e;

  public Object invokeSuper(Object obj, Object[] args) throws Throwable {

   try {

   init();

   FastClassInfo fci = fastClassInfo;

   // f2表示UserService代理类的FastClass代理类,i2表示代理方法的下标,这里就是去执行CGLIB$test$0方法,具体执行的是哪个对象就看obj

   return fci.f2.invoke(fci.i2, obj, args);

   } catch (InvocationTargetException e) {

   throw e.getTargetException();

  }

 

   说明

   1.说白了,这个两个方法本身是根据不同的索引文件去找对应的方法,然后用传入对象,调用返回的方法。

   2.这里面涉及了另外的两个字节码文件(便是上面存储路径下的):

   TestObject$$EnhancerByCGLIB$$783a36a0$$FastClassByCGLIB$$626f6578.class(这里面是代理类的方法索引)

   TestObject$$FastClassByCGLIB$$a3bbba2f.class(这里面是目标类的方法索引)

  

   (3)FastClassInfo的生成过程

  

private void init(){

 

   if (fastClassInfo == null) {

   //采用双重判断+加锁达到只生成一次

   synchronized (initLock) {

   if (fastClassInfo == null) {

   // CreateInfo中存储了代理类和被代理类

   CreateInfo ci = createInfo;

   FastClassInfo fci = new FastClassInfo();

   fci.f1 = helper(ci, ci.c1); // 被代理类的FastClass代理类,也就是TestObject$$FastClassByCGLIB$$a3bbba2f.class

   fci.f2 = helper(ci, ci.c2); // 代理类的FastClass代理类,也就是TestObject$$EnhancerByCGLIB$$783a36a0$$FastClassByCGLIB$$626f6578.class

  
// 预先生成每个方法所对应的下标,调用时就可以直接利用下标找到方法了,性能高

   fci.i1 = fci.f1.getIndex(sig1); // 获取方法签名sig1在被代理类的FastClass代理类中的下标,后续根据下标找到对应的方法,sig1表示被代理方法test()

   fci.i2 = fci.f2.getIndex(sig2); // 获取方法签名sigsig2在代理类的FastClass代理类中的下标,后续根据下标找到对应的方法,sig2表示代理方法CGLIB$test$0()

   fastClassInfo = fci;

   createInfo = null;

  }

 

   TestObject$$EnhancerByCGLIB$$783a36a0$$FastClassByCGLIB$$626f6578.class代码展示(已经进行了部分删。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: