`
heavensay
  • 浏览: 9611 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

CGLIB学习笔记

    博客分类:
  • Java
 
阅读更多

     一般使用cglib最多的是Enhance类。


1Enhance运用的一个例子

Enhance生成动态子类以支持AOP。


 

public class MyTestEnhancer extends TestCase {
    private static final MethodInterceptor TEST_INTERCEPTOR = new TestInterceptor();
    
    @Override
    protected void setUp() throws Exception {
    	System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "C:/Users/admin/Desktop/cg_lib");
    }
    
    public void test1(){
    	A a = (A)Enhancer.create(A.class, new CallBackImpl1());   // -- index1
    	A a2 = (A)Enhancer.create(A.class, new CallBackImpl1());
    	a.getProtectedString();
    	a.doPublic();
    	a.doFinal();
    }
    
}

class A{
	
	protected String getProtectedString(){
		return " then getProtectedString method is invoked ";
	}
	
	public void doPublic(){
		System.out.println(" dopublic is invoked ");
	}
	
	public final String doFinal(){	
		return " final method is invoked ";
	}
}

class CallBackImpl1 implements MethodInterceptor{
	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		System.out.println(" before "+method.getName()+" invoke ");
		Object o = proxy.invokeSuper(obj, args);
		System.out.println(" the return value of the  mehod of "+method.getName()+" : "+o);
		System.out.println(" after "+method.getName()+" invoke ");
		return o;
	}
}
 

 


上述代码输出结果:



 before getProtectedString invoke 
 the return value of the  mehod of getProtectedString :  then getProtectedString method is invoked 
 after getProtectedString invoke 
 before doPublic invoke 
 dopublic is invoked 
 the return value of the  mehod of doPublic : null
 after doPublic invoke 

 



  • 从输出结果中看出调用doPublic()和getProtectedString()方法时,多增加了一些输出内容。

为什么这样呢?

      原理也就是在于A a = (A)Enhancer.create(A.class, new CallBackImpl1())这行代码中返回的实例a的真正类型是类A的子类,Cglib已经改写了A,并生成了他的子类,然后然后这个生成子类的实例。

先看看这个这类的修饰符:


public class A$$EnhancerByCGLIB$$3425c0b1 extends A
  implements Factory


      可以看出Enhance.create(...)生成的类已经是原来类A的子类了,并且实现了 net.sf.cglib.Factory接口。

在上面输出结果中也没看出执行doFinal()方法时,没有什么信息打印出来,而且在动态生成的A$$EnhancerByCGLIB$$3425c0b1中也找不到此方法。

其实这也是正常的,java语法中一个类的final方法就不能被子类重写,而且动态生成的类于原来的类为继承关系,所以自然不能重写。所以a.doFinal(...)执行的是原来的方法。



      再来看看动态生成的A的子类,通过查看反编译代码,发现基本每个被重写的方法都会有 method()和CGLIB$method()这种成对出现的方法



  protected final String getProtectedString(){}
  final String CGLIB$getProtectedString$0(){}
  public final void doPublic(){}
  final void CGLIB$doPublic$1(){}
  .....
  .....

  

   上图为动态生成的类的一些属性.

 


方法中具体的实现:



  final String CGLIB$getProtectedString$0()
  {
    return super.getProtectedString();
  }


  protected final String getProtectedString()
  {
    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
    if (tmp4_1 == null)
    {
      tmp4_1;
      CGLIB$BIND_CALLBACKS(this);
    }
    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;
    if (tmp17_14 != null)
      return (String)tmp17_14.intercept(this, CGLIB$getProtectedString$0$Method, CGLIB$emptyArgs, CGLIB$getProtectedString$0$Proxy);
    return super.getProtectedString();
  }

    


      从此方法中可以看出动态生成的A的已经改写了getProtectedString()方法,

其中tmp17_14.intercept(...)就是调用我们CallBackImpl1的intercept(...)方法,此方法是实现接口MethodInterceptor接口中得方法。

 

  •       在MethodInterceptor.intercept(...)中我们一般调用proxy.invokeSuper(...)方法来调用我们原始类中得方法,当然在执行invokeSupper()方法前或后可以做一些自己想做的操作。包括

 

权限判断,日志记录等,Aop的切点也就是在这里。

 

  •       在调用a的一个方法的时候还会自动生成2个类,类名如A$$FastClassByCGLIB$$61e6ad28.class,A$$EnhancerByCGLIB$$586ca680$$FastClassByCGLIB$$23daa21b.class,这2个额外生成的类作用在于当我们调用一个方法时,不通过反射来调用,而是通过类似于数组下标的方式来定位方法,直接进行类方法的执行。

 


	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		//before dosomething
		Object o = proxy.invokeSuper(obj, args);
               //after dosomething
	}

 

生成的2个FlassClass过程:

 

 


 

 

 

 

       FlassClass.invoke执行细节:


 

A$$EnhancerByCGLIB$$f84d7df$$FastClassByCGLIB$$1098f999{  
public Object invoke(int paramInt, Object paramObject, Object[] paramArrayOfObject)
    throws InvocationTargetException
  {
    // Byte code:
       0: aload_2 
       1: checkcast 159	net/sf/cglib/mytest/A$$EnhancerByCGLIB$$f84d7df
       4: iload_1   //paramInt参数入栈
       5: tableswitch	default:+403 -> 408, 0:+131->136..... //通过paramInt也就相当于数组小标志,定位到方法执行的代码段
.....
.....
       148: aload_3
       149: iconst_0
       150: aaload
       151: invokevirtual 166	net/sf/cglib/mytest/A$$EnhancerByCGLIB$$f84d7df:equals	(Ljava/lang/Object;)Z //直接快速的执行方法
.....
.....
}
}

 

 

  •       MethodProxy proxy还有一个invoke(Object obj, Object[] args)方法。此方法与invokeSuper(...)不同在于前一个方法调用的是fci.f2.invoke();后一个调用fci.f1.invoke();其中f1和f2就是生成的2个FastClass。之后调用invoke(...)方法传入的参数obj

 

 

    public Object invoke(Object obj, Object[] args) throws Throwable {
        try {
            init();
            FastClassInfo fci = fastClassInfo;
            return fci.f1.invoke(fci.i1, obj, args);
    }

 

 

 

 

	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		//before dosomething 
               //注意如果proxy.invoke()中得参数obj为intercept()的参数obj的话会会造成内存溢出。
              //原因在于proxy.invoke()方法中,最终执行的是obj中被重写的方法,
             //而每次执行的时候又会执行intercept()方法,导致了死循环。
		Object o = proxy.invoke(obj, args);
               //after dosomething
	}
 
 

 

 



 





   Enhance提供的功能不只于此


Enhance.create(Class superclass, Class[] interfaces, CallbackFilter filter, Callback[] callbacks) 

 


上述方法中,用户可以实现一系列的callbacks,用于拦截,CallbackFilter作用在于过滤callbacks,使一个方法只能被一个callback拦截。

例子



    public void test2(){
    	A a = (A)Enhancer.create(A.class,null,new CallBackFilterImpl(),new Callback[]{ new CallBackImpl1(),new CallBackImpl2()});
    	a.getProtectedString();
    	a.doPublic();
    }


class CallBackImpl2 implements MethodInterceptor{
	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		System.out.println(" CallBackImpl2 before "+method.getName()+" invoke ");
		Object o = proxy.invokeSuper(obj, args);
		System.out.println(" CallBackImpl2 the return value of the  mehod of "+method.getName()+" : "+o);
		System.out.println(" CallBackImpl2 after "+method.getName()+" invoke ");
		return o;
	}
}

class CallBackFilterImpl implements CallbackFilter{
	@Override
	public int accept(Method method) {
		if ("doPublic".equals(method.getName())){
			return 1;
		}
		return 0;
	}




输出结果:
 before getProtectedString invoke 
 the return value of the  mehod of getProtectedString :  then getProtectedString method is invoked 
 after getProtectedString invoke 
 CallBackImpl2 before doPublic invoke 
 dopublic is invoked 
 CallBackImpl2 the return value of the  mehod of doPublic : null
 CallBackImpl2 after doPublic invoke 



从输出结果中可以看出getProtectedString()方法被CallBackImpl1拦截了,

doPublic()方法被CallBackImpl2拦截了。



 CallBackFilterImpl 就是用于过滤callback,方法accept(Method method)的返回值,就是method方法所采用的callback。

1代表采用Enhance.create(Class superclass, Class[] interfaces, CallbackFilter filter, Callback[] callbacks) 方法中,

callbacks[1],0代表采用callbacks[0]进行拦截。




2 Enhance.create()动态创建类的过程


    public static Object create(Class superclass, Class[] interfaces, CallbackFilter filter, Callback[] callbacks) {
        Enhancer e = new Enhancer();
        e.setSuperclass(superclass); //要继承的父类
        e.setInterfaces(interfaces); //要实现的接口
        e.setCallbackFilter(filter); // filter用于过滤callbacks,使每个方法对应各                                                                                                                           //                                                  自的callback
        e.setCallbacks(callbacks);//拦截回调的实现
        return e.create();
    }
//设置各种创建类所必要的信息


 

 

    private static final EnhancerKey KEY_FACTORY =
      (EnhancerKey)KeyFactory.create(EnhancerKey.class);

        validate();
        if (superclass != null) {
            setNamePrefix(superclass.getName());
        } else if (interfaces != null) {
            setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
        }
                    //KEY_FACTORY.newInstance()方法会根据里
//面的各个参数生成一个key,用于缓存生成的动态class,map(key,class)。
        return super.create(KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
                                                    ReflectUtils.getNames(interfaces),
                                                    filter,
                                                    callbackTypes,
                                                    useFactory,
                                                    interceptDuringConstruction,
                                                    serialVersionUID));


 
 

 

 

 

    上述代码中,KeyFactory.newInstance(...)作用在于生成一个key用于映射各个动态生成的类.

 


  protected Object create(Object key) {
        try {
        	Class gen = null;
        	
                Map cache2 = null;
                cache2 = (Map)source.cache.get(loader);
 
			//根据key得到class,如果class曾动态生成过,且没有被回收,则直接拿来使用,不需要重新生成
                    Reference ref = (Reference)cache2.get(key);
                    gen = (Class) (( ref == null ) ? null : ref.get()); 

                if (gen == null) {
                        this.key = key;
                        if (gen == null) {
			//动态生成的class字节码。Enhance重写了generateClass方法
                       //这步就是关键的生成动态字节码
                            byte[] b = strategy.generate(this);
                            String className = ClassNameReader.getClassName(new ClassReader(b));
                            getClassNameCache(loader).add(className);
				//b:动态生成的字节码。  加载b,生成Class对象
                            gen = ReflectUtils.defineClass(className, b, loader);
                        }
                       
                        if (useCache) {
                            cache2.put(key, new WeakReference(gen));
                        }
			// 返回字节码生成的一个实例
                        return firstInstance(gen);
    }




 public void generateClass(ClassVisitor v) throws Exception {
        Class sc = (superclass == null) ? Object.class : superclass;
        //如果类的修饰符为final,则不能动态生成子类
        if (TypeUtils.isFinal(sc.getModifiers()))
            throw new IllegalArgumentException("Cannot subclass final class " + sc);
        List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));

         //方法包括类的父类的所有方法,接口及接口父类的方法
        getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);

        //此类是cglib包装asm字节码框架,用于直接对字节码操作
        ClassEmitter e = new ClassEmitter(v);
        
         //开始创建class字节码
        e.begin_class(Constants.V1_2,
                      Constants.ACC_PUBLIC,
                      getClassName(),
                      Type.getType(sc),
                      (useFactory ?
                       TypeUtils.add(TypeUtils.getTypes(interfaces), FACTORY) :
                       TypeUtils.getTypes(interfaces)),
                      Constants.SOURCE_FILE);
        
        List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());

        //定义一些属性
        e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null);
        if (!interceptDuringConstruction) {
            e.declare_field(Constants.ACC_PRIVATE, CONSTRUCTED_FIELD, Type.BOOLEAN_TYPE, null);
        }
        e.declare_field(Constants.PRIVATE_FINAL_STATIC, THREAD_CALLBACKS_FIELD, THREAD_LOCAL, null);
        e.declare_field(Constants.PRIVATE_FINAL_STATIC, STATIC_CALLBACKS_FIELD, CALLBACK_ARRAY, null);
        if (serialVersionUID != null) {
            e.declare_field(Constants.PRIVATE_FINAL_STATIC, Constants.SUID_FIELD_NAME, Type.LONG_TYPE, serialVersionUID);
        }

        for (int i = 0; i < callbackTypes.length; i++) {
            e.declare_field(Constants.ACC_PRIVATE, getCallbackField(i), callbackTypes[i], null);
        }

        //构造方法,其中overwrite原来类的方法
        emitMethods(e, methods, actualMethods);
        
        emitConstructors(e, constructorInfo);
        emitSetThreadCallbacks(e);
        emitSetStaticCallbacks(e);
        emitBindCallbacks(e);

        //userFactory,就是生成的class所implements的Factory接口,
        //并且实现此接口中得方法。
        if (useFactory) {
            int[] keys = getCallbackKeys();
            emitNewInstanceCallbacks(e);
            emitNewInstanceCallback(e);
            emitNewInstanceMultiarg(e, constructorInfo);
            emitGetCallback(e, keys);
            emitSetCallback(e, keys);
            emitGetCallbacks(e);
            emitSetCallbacks(e);
        }
        //如果有static{}快,生成static块字节码, 生成class结束
        e.end_class();
    }

 







动态生成的A的反编译代码
package net.sf.cglib.mytest;

import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class A$$EnhancerByCGLIB$$3f79b2af extends A
  implements Factory
{
  private boolean CGLIB$BOUND;
  private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
  private static final Callback[] CGLIB$STATIC_CALLBACKS;
  private MethodInterceptor CGLIB$CALLBACK_0;
  private MethodInterceptor CGLIB$CALLBACK_1;
  private static final Method CGLIB$getProtectedString$0$Method;
  private static final MethodProxy CGLIB$getProtectedString$0$Proxy;
  private static final Object[] CGLIB$emptyArgs;
  private static final Method CGLIB$doPublic$1$Method;
  private static final MethodProxy CGLIB$doPublic$1$Proxy;
  private static final Method CGLIB$hashCode$2$Method;
  private static final MethodProxy CGLIB$hashCode$2$Proxy;
  private static final Method CGLIB$finalize$3$Method;
  private static final MethodProxy CGLIB$finalize$3$Proxy;
  private static final Method CGLIB$clone$4$Method;
  private static final MethodProxy CGLIB$clone$4$Proxy;
  private static final Method CGLIB$equals$5$Method;
  private static final MethodProxy CGLIB$equals$5$Proxy;
  private static final Method CGLIB$toString$6$Method;
  private static final MethodProxy CGLIB$toString$6$Proxy;

  static void CGLIB$STATICHOOK1()
  {
    CGLIB$THREAD_CALLBACKS = new ThreadLocal();
    CGLIB$emptyArgs = new Object[0];
    Class localClass1 = Class.forName("net.sf.cglib.mytest.A$$EnhancerByCGLIB$$3f79b2af");
    Class localClass2;
    Method[] tmp95_92 = ReflectUtils.findMethods(new String[] { "hashCode", "()I", "finalize", "()V", "clone", "()Ljava/lang/Object;", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;" }, (localClass2 = Class.forName("java.lang.Object")).getDeclaredMethods());
    CGLIB$hashCode$2$Method = tmp95_92[0];
    CGLIB$hashCode$2$Proxy = MethodProxy.create(localClass2, localClass1, "()I", "hashCode", "CGLIB$hashCode$2");
    Method[] tmp115_95 = tmp95_92;
    CGLIB$finalize$3$Method = tmp115_95[1];
    CGLIB$finalize$3$Proxy = MethodProxy.create(localClass2, localClass1, "()V", "finalize", "CGLIB$finalize$3");
    Method[] tmp135_115 = tmp115_95;
    CGLIB$clone$4$Method = tmp135_115[2];
    CGLIB$clone$4$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$4");
    Method[] tmp155_135 = tmp135_115;
    CGLIB$equals$5$Method = tmp155_135[3];
    CGLIB$equals$5$Proxy = MethodProxy.create(localClass2, localClass1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$5");
    Method[] tmp175_155 = tmp155_135;
    CGLIB$toString$6$Method = tmp175_155[4];
    CGLIB$toString$6$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/String;", "toString", "CGLIB$toString$6");
    tmp175_155;
    Method[] tmp233_230 = ReflectUtils.findMethods(new String[] { "getProtectedString", "()Ljava/lang/String;", "doPublic", "()V" }, (localClass2 = Class.forName("net.sf.cglib.mytest.A")).getDeclaredMethods());
    CGLIB$getProtectedString$0$Method = tmp233_230[0];
    CGLIB$getProtectedString$0$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/String;", "getProtectedString", "CGLIB$getProtectedString$0");
    Method[] tmp253_233 = tmp233_230;
    CGLIB$doPublic$1$Method = tmp253_233[1];
    CGLIB$doPublic$1$Proxy = MethodProxy.create(localClass2, localClass1, "()V", "doPublic", "CGLIB$doPublic$1");
    tmp253_233;
    return;
  }

  final String CGLIB$getProtectedString$0()
  {
    return super.getProtectedString();
  }

  protected final String getProtectedString()
  {
    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
    if (tmp4_1 == null)
    {
      tmp4_1;
      CGLIB$BIND_CALLBACKS(this);
    }
    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;
    if (tmp17_14 != null)
      return (String)tmp17_14.intercept(this, CGLIB$getProtectedString$0$Method, CGLIB$emptyArgs, CGLIB$getProtectedString$0$Proxy);
    return super.getProtectedString();
  }

  final void CGLIB$doPublic$1()
  {
    super.doPublic();
  }

  public final void doPublic()
  {
    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_1;
    if (tmp4_1 == null)
    {
      tmp4_1;
      CGLIB$BIND_CALLBACKS(this);
    }
    if (this.CGLIB$CALLBACK_1 != null)
      return;
    super.doPublic();
  }

  final int CGLIB$hashCode$2()
  {
    return super.hashCode();
  }

  public final int hashCode()
  {
    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
    if (tmp4_1 == null)
    {
      tmp4_1;
      CGLIB$BIND_CALLBACKS(this);
    }
    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;
    if (tmp17_14 != null)
    {
      Object tmp36_31 = tmp17_14.intercept(this, CGLIB$hashCode$2$Method, CGLIB$emptyArgs, CGLIB$hashCode$2$Proxy);
      tmp36_31;
      return tmp36_31 == null ? 0 : ((Number)tmp36_31).intValue();
    }
    return super.hashCode();
  }

  final void CGLIB$finalize$3()
    throws Throwable
  {
    super.finalize();
  }

  protected final void finalize()
    throws Throwable
  {
    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
    if (tmp4_1 == null)
    {
      tmp4_1;
      CGLIB$BIND_CALLBACKS(this);
    }
    if (this.CGLIB$CALLBACK_0 != null)
      return;
    super.finalize();
  }

  final Object CGLIB$clone$4()
    throws CloneNotSupportedException
  {
    return super.clone();
  }

  protected final Object clone()
    throws CloneNotSupportedException
  {
    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
    if (tmp4_1 == null)
    {
      tmp4_1;
      CGLIB$BIND_CALLBACKS(this);
    }
    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;
    if (tmp17_14 != null)
      return tmp17_14.intercept(this, CGLIB$clone$4$Method, CGLIB$emptyArgs, CGLIB$clone$4$Proxy);
    return super.clone();
  }

  final boolean CGLIB$equals$5(Object paramObject)
  {
    return super.equals(paramObject);
  }

  public final boolean equals(Object paramObject)
  {
    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
    if (tmp4_1 == null)
    {
      tmp4_1;
      CGLIB$BIND_CALLBACKS(this);
    }
    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;
    if (tmp17_14 != null)
    {
      Object tmp41_36 = tmp17_14.intercept(this, CGLIB$equals$5$Method, new Object[] { paramObject }, CGLIB$equals$5$Proxy);
      tmp41_36;
      return tmp41_36 == null ? false : ((Boolean)tmp41_36).booleanValue();
    }
    return super.equals(paramObject);
  }

  final String CGLIB$toString$6()
  {
    return super.toString();
  }

  public final String toString()
  {
    MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
    if (tmp4_1 == null)
    {
      tmp4_1;
      CGLIB$BIND_CALLBACKS(this);
    }
    MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;
    if (tmp17_14 != null)
      return (String)tmp17_14.intercept(this, CGLIB$toString$6$Method, CGLIB$emptyArgs, CGLIB$toString$6$Proxy);
    return super.toString();
  }

  public static MethodProxy CGLIB$findMethodProxy(Signature paramSignature)
  {
    String tmp4_1 = paramSignature.toString();
    switch (tmp4_1.hashCode())
    {
    case -1574182249:
      if (tmp4_1.equals("finalize()V"))
        return CGLIB$finalize$3$Proxy;
    case -508378822:
    case -488807391:
    case 1384608372:
    case 1826985398:
    case 1913648695:
    case 1984935277:
    }
  }

  public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback)
  {
    CGLIB$THREAD_CALLBACKS.set(paramArrayOfCallback);
  }

  public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] paramArrayOfCallback)
  {
    CGLIB$STATIC_CALLBACKS = paramArrayOfCallback;
  }

  private static final void CGLIB$BIND_CALLBACKS(Object paramObject)
  {
    // Byte code:
    //   0: aload_0
    //   1: checkcast 2	net/sf/cglib/mytest/A$$EnhancerByCGLIB$$3f79b2af
    //   4: astore_1
    //   5: aload_1
    //   6: getfield 215	net/sf/cglib/mytest/A$$EnhancerByCGLIB$$3f79b2af:CGLIB$BOUND	Z
    //   9: ifne +52 -> 61
    //   12: aload_1
    //   13: iconst_1
    //   14: putfield 215	net/sf/cglib/mytest/A$$EnhancerByCGLIB$$3f79b2af:CGLIB$BOUND	Z
    //   17: getstatic 25	net/sf/cglib/mytest/A$$EnhancerByCGLIB$$3f79b2af:CGLIB$THREAD_CALLBACKS	Ljava/lang/ThreadLocal;
    //   20: invokevirtual 218	java/lang/ThreadLocal:get	()Ljava/lang/Object;
    //   23: dup
    //   24: ifnonnull +15 -> 39
    //   27: pop
    //   28: getstatic 213	net/sf/cglib/mytest/A$$EnhancerByCGLIB$$3f79b2af:CGLIB$STATIC_CALLBACKS	[Lnet/sf/cglib/proxy/Callback;
    //   31: dup
    //   32: ifnonnull +7 -> 39
    //   35: pop
    //   36: goto +25 -> 61
    //   39: checkcast 219	[Lnet/sf/cglib/proxy/Callback;
    //   42: aload_1
    //   43: swap
    //   44: dup2
    //   45: iconst_1
    //   46: aaload
    //   47: checkcast 50	net/sf/cglib/proxy/MethodInterceptor
    //   50: putfield 64	net/sf/cglib/mytest/A$$EnhancerByCGLIB$$3f79b2af:CGLIB$CALLBACK_1	Lnet/sf/cglib/proxy/MethodInterceptor;
    //   53: iconst_0
    //   54: aaload
    //   55: checkcast 50	net/sf/cglib/proxy/MethodInterceptor
    //   58: putfield 38	net/sf/cglib/mytest/A$$EnhancerByCGLIB$$3f79b2af:CGLIB$CALLBACK_0	Lnet/sf/cglib/proxy/MethodInterceptor;
    //   61: return
  }

  public Object newInstance(Callback[] paramArrayOfCallback)
  {
    CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback);
    CGLIB$SET_THREAD_CALLBACKS(null);
    return new 3f79b2af();
  }

  public Object newInstance(Callback paramCallback)
  {
    throw new IllegalStateException("More than one callback object required");
    CGLIB$SET_THREAD_CALLBACKS(null);
    return new 3f79b2af();
  }

  public Object newInstance(Class[] paramArrayOfClass, Object[] paramArrayOfObject, Callback[] paramArrayOfCallback)
  {
    CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback);
    Class[] tmp9_8 = paramArrayOfClass;
    switch (tmp9_8.length)
    {
    case 0:
      tmp9_8;
      break;
    default:
      new 3f79b2af();
      throw new IllegalArgumentException("Constructor not found");
    }
    CGLIB$SET_THREAD_CALLBACKS(null);
  }

  public Callback getCallback(int paramInt)
  {
    CGLIB$BIND_CALLBACKS(this);
    switch (paramInt)
    {
    case 0:
      break;
    case 1:
      break;
    }
    return null;
  }

  public void setCallback(int paramInt, Callback paramCallback)
  {
    switch (paramInt)
    {
    case 0:
      this.CGLIB$CALLBACK_0 = ((MethodInterceptor)paramCallback);
      break;
    case 1:
      this.CGLIB$CALLBACK_1 = ((MethodInterceptor)paramCallback);
      break;
    }
  }

  public Callback[] getCallbacks()
  {
    CGLIB$BIND_CALLBACKS(this);
    return new Callback[] { this.CGLIB$CALLBACK_0, this.CGLIB$CALLBACK_1 };
  }

  public void setCallbacks(Callback[] paramArrayOfCallback)
  {
    Callback[] tmp2_1 = paramArrayOfCallback;
    this.CGLIB$CALLBACK_0 = ((MethodInterceptor)tmp2_1[0]);
    this.CGLIB$CALLBACK_1 = ((MethodInterceptor)tmp2_1[1]);
  }

  static
  {
    CGLIB$STATICHOOK1();
  }
}

 



 

  • 大小: 22.6 KB
  • 大小: 36.5 KB
  • 大小: 22.9 KB
分享到:
评论

相关推荐

    Spring学习笔记(14)----使用CGLIB实现AOP功能

    在本篇Spring学习笔记中,我们将探讨如何使用CGLIB库来实现AOP功能。 CGLIB(Code Generation Library)是一个强大的高性能的代码生成库,它被广泛用于动态代理和运行时织入AOP切面。在Spring中,如果目标类没有...

    spring aop 学习笔记

    本学习笔记将深入探讨Spring AOP的核心概念、工作原理以及实际应用。 1. **核心概念** - **切面(Aspect)**:切面是关注点的模块化,包含业务逻辑之外的横切关注点,如日志、事务管理。 - **连接点(Join Point...

    hibernate框架学习笔记整理

    ### hibernate框架学习笔记整理 #### 一、Hibernate框架简介 **Hibernate框架**是一种用于Java应用的**对象关系映射**(Object-Relational Mapping, ORM)解决方案,它允许开发者使用面向对象的方式操作数据库中的表...

    Spring技术内幕 学习笔记

    《Spring技术内幕 学习笔记》是一份深入探讨Spring框架核心机制的学习资料,结合作者zzc1684在iteye博客上的博文,我们可以从中学习到Spring框架的多个重要知识点。Spring作为Java企业级应用开发的基石,其设计思想...

    Spring编程学习笔记

    ### Spring编程学习笔记知识点概述 #### 一、Spring框架简介 Spring框架是一个开源的轻量级Java开发框架,主要用于简化企业级应用的开发工作。它提供了全面的基础架构支持,包括但不限于依赖注入(Dependency ...

    Hibernate学习笔记源码及文档

    学习笔记涵盖了Hibernate的基础概念、配置、实体类的创建、数据类型映射、关系映射(一对一、一对多、多对多)、查询语言HQL、 Criteria API、CGLIB动态代理等核心内容。笔记详细记录了每个知识点的原理和实践步骤...

    spring学习笔记(十四)

    【标题】"Spring学习笔记(十四)"主要涵盖了Spring框架中的AOP(面向切面编程)和CGLIB库的应用,这两个知识点在Java开发中尤为重要,尤其是对于构建灵活、可维护的大型企业级应用。 首先,Spring框架是Java开发中...

    jpa学习笔记

    ### JPA 学习笔记详解 #### 一、JPA 概述 Java Persistence API (JPA) 是 Sun 公司提出的一种 Java 持久层标准,它为 Java 开发者提供了一种对象关系映射 (ORM) 的工具来管理 Java 应用程序中的关系型数据。JPA ...

    spring学习笔记(十三)

    【标题】"Spring学习笔记(十三)"主要涉及的是Spring框架中的AOP(面向切面编程)部分,特别是关于CGLIB动态代理的实现。在Spring中,AOP是一种强大的编程模型,它允许开发者定义“切面”,即关注点的模块化,如日志...

    spring学习笔记(八)

    【标题】"Spring学习笔记(八)"主要涵盖了Spring框架中的动态代理机制,这是Spring AOP(面向切面编程)的核心技术之一。动态代理允许我们在不修改原有代码的情况下,为对象添加额外的功能,如日志、事务管理等。在这...

    Spring学习笔记

    ### Spring学习笔记:深入理解AOP与Annotation驱动的动态代理 #### 核心知识点解析: 在探讨Spring框架中AOP(面向切面编程)及基于Annotation的动态代理之前,我们首先需要了解AOP的基本概念及其在Spring中的实现...

    Spring学习笔记1

    在本篇Spring学习笔记中,我们将深入探讨Spring的几个关键知识点,包括其优点、AOP的实现原理以及声明式事务管理。 首先,Spring的优点在于它的轻量级特性,它不对现有类结构造成入侵,允许开发者专注于业务逻辑。...

    Spring2.5学习笔记

    ### Spring2.5 学习笔记详解 #### 一、Spring 框架简介 Spring 是一个开源的轻量级 Java 开发框架,主要用于简化企业级应用的开发工作。Spring 提供了一系列强大的功能,比如控制反转 (Inversion of Control, IOC)...

    Spring 学习笔记六

    在本篇"Spring 学习笔记六"中,我们将深入探讨Spring框架的核心概念和技术细节,同时结合源码分析,以提升对Spring的理解和应用能力。本文档主要关注Spring的依赖注入(Dependency Injection,DI)机制、AOP(面向切...

    spring学习笔记,包括源码学习

    这个"spring学习笔记,包括源码学习"的资料很可能包含了一系列关于Spring框架的核心概念、配置、使用方法以及深入源码的解析。 首先,让我们来了解一下Spring框架的基础知识。Spring的核心特性是依赖注入,它允许...

    Spring 学习笔记四

    【Spring 学习笔记四】 在本篇Spring学习笔记中,我们将深入探讨Spring框架的核心特性,包括依赖注入(Dependency Injection,DI)、AOP(面向切面编程)以及Spring的源码解析,同时也会介绍一些实用的开发工具。...

    Spring的学习笔记

    以下将详细介绍Spring学习笔记中的主要知识点。 **面向抽象编程** 面向抽象编程是一种设计原则,强调在代码中使用接口或抽象类,而不是具体实现类。这使得系统更具有灵活性,易于扩展和维护。在Spring框架中,我们...

    学习笔记动态SQL:Demo.zip

    本学习笔记将深入探讨动态SQL的概念及其在MyBatis中的应用,同时结合相关库如Javassist、CGLIB等进行解析。 首先,动态SQL的核心思想是避免硬编码大量的静态SQL语句,而是通过程序逻辑来动态生成SQL。这提高了代码...

    传智播客Spring2.5.6学习笔记最新整理

    ### Spring2.5.6 学习笔记精粹解析 #### 一、Spring框架环境搭建与JAR包配置 在开始深入Spring框架的学习之前,首先需要确保开发环境正确配置Spring框架。按照“传智播客Spring2.5.6学习笔记最新整理”的指引,...

Global site tag (gtag.js) - Google Analytics