一般使用cglib最多的是Enhance类。
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
为什么这样呢?
原理也就是在于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接口中得方法。
权限判断,日志记录等,Aop的切点也就是在这里。
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 //直接快速的执行方法 ..... ..... } }
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]进行拦截。
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();
}
}