CGlib概述:
cglib(
Code Generation Library)是一個(gè)強(qiáng)大的,高性能,高質(zhì)量的Code生成類(lèi)庫(kù)。它可以在運(yùn)行期擴(kuò)展Java類(lèi)與實(shí)現(xiàn)Java接口。
cglib封裝了asm,可以在運(yùn)行期動(dòng)態(tài)生成新的class。
cglib用于AOP,jdk中的proxy必須基于接口,cglib卻沒(méi)有這個(gè)限制。
CGlib應(yīng)用:
以一個(gè)實(shí)例在簡(jiǎn)單介紹下cglib的應(yīng)用。
我們模擬一個(gè)虛擬的場(chǎng)景,關(guān)于信息的管理。
1)原始需求是任何人可以操作信息的create,update,delete,query操作。
InfoManager.java--封裝對(duì)信息的操作
public class InfoManager {
// 模擬查詢(xún)操作
public void query() {
System.out.println("query");
}
// 模擬創(chuàng)建操作
public void create() {
System.out.println("create");
}
// 模擬更新操作
public void update() {
System.out.println("update");
}
// 模擬刪除操作
public void delete() {
System.out.println("delete");
}
}
InfoManagerFactory.java--工廠類(lèi)
public class InfoManagerFactory {
private static InfoManager manger = new InfoManager();
/**
* 創(chuàng)建原始的InfoManager
*
* @return
*/
public static InfoManager getInstance() {
return manger;
}
}
client.java--供客戶(hù)端調(diào)用
public class Client {
public static void main(String[] args) {
Client c = new Client();
c.anyonecanManager();
}
/**
* 模擬:沒(méi)有任何權(quán)限要求,任何人都可以操作
*/
public void anyonecanManager() {
System.out.println("any one can do manager");
InfoManager manager = InfoManagerFactory.getInstance();
doCRUD(manager);
separatorLine();
}
/**
* 對(duì)Info做增加/更新/刪除/查詢(xún)操作
*
* @param manager
*/
private void doCRUD(InfoManager manager) {
manager.create();
manager.update();
manager.delete();
manager.query();
}
/**
* 加一個(gè)分隔行,用于區(qū)分
*/
private void separatorLine() {
System.out.println("################################");
}
}
至此,沒(méi)有涉及到cglib的內(nèi)容,因?yàn)樾枨筇?jiǎn)單了,但是接下來(lái),需求發(fā)生了改變,要求:
2)只有一個(gè)叫“maurice”的用戶(hù)登錄,才允許對(duì)信息進(jìn)行create,update,delete,query的操作。
怎么辦?難道在每個(gè)方法前,都加上一個(gè)權(quán)限判斷嗎?這樣重復(fù)邏輯太多了,于是乎想到了Proxy(代理模式),但是原先的InfoManager也沒(méi)有實(shí)現(xiàn)接口,不能采用jdk的proxy。那么cglib在這邊就要隆重登場(chǎng)。
一旦使用cgblig,只需要添加一個(gè)MethodInterceptor的類(lèi)以及修改factory代碼就可以實(shí)現(xiàn)這個(gè)需求。
AuthProxy.java--權(quán)限校驗(yàn)代理類(lèi)
public class AuthProxy implements MethodInterceptor {
private String name; // 會(huì)員登錄名
public AuthProxy(String name) {
this.name = name;
}
/**
* 權(quán)限校驗(yàn),如果會(huì)員名為:maurice,則有權(quán)限做操作,否則提示沒(méi)有權(quán)限
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
if (!"maurice".equals(this.name)) {
System.out.println("AuthProxy:you have no permits to do manager!");
return null;
}
return proxy.invokeSuper(obj, args);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
InfoManagerFactory.java--代碼變動(dòng)如下:
public class InfoManagerFactory {
/**
* 創(chuàng)建帶有權(quán)限檢驗(yàn)的InfoManager
*
* @param auth
* @return
*/
public static InfoManager getAuthInstance(AuthProxy auth) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(InfoManager.class);
enhancer.setCallback(auth);
return (InfoManager) enhancer.create();
}
}
client.java--代碼修改如下
public class Client {
public static void main(String[] args) {
Client c = new Client();
c.haveNoAuthManager();
c.haveAuthManager();
}
/**
* 模擬:登錄會(huì)員沒(méi)有權(quán)限
*/
public void haveNoAuthManager() {
System.out.println("the loginer's name is not maurice,so have no permits do manager
");
InfoManager noAuthManager = InfoManagerFactory.getAuthInstance(new AuthProxy("maurice1"));
doCRUD(noAuthManager);
separatorLine();
}
/**
* 模擬:登錄會(huì)員有權(quán)限
*/
public void haveAuthManager() {
System.out.println("the loginer's name is maurice,so have permits do manager
");
InfoManager authManager = InfoManagerFactory.getAuthInstance(new AuthProxy("maurice"));
doCRUD(authManager);
separatorLine();
}
/**
* 對(duì)Info做增加/更新/刪除/查詢(xún)操作
*
* @param manager
*/
private void doCRUD(InfoManager manager) {
manager.create();
manager.update();
manager.delete();
manager.query();
}
/**
* 加一個(gè)分隔行,用于區(qū)分
*/
private void separatorLine() {
System.out.println("################################");
}
}
執(zhí)行下代碼,發(fā)現(xiàn)這時(shí)client端中已經(jīng)加上了權(quán)限校驗(yàn)。
同樣是InfoManager,為什么這時(shí)能多了權(quán)限的判斷呢?Factory中
enhancer.create()返回的到底是什么對(duì)象呢?這個(gè)疑問(wèn)將在第三部分CGlib中解釋。
這邊的代碼,其實(shí)是介紹了cglib中的enhancer功能.
到這里,參照上面的代碼,就可以使用cglib帶來(lái)的aop功能了。但是為了更多介紹下cglib的功能,模擬需求再次發(fā)生變化:
3)由于query功能用戶(hù)maurice才能使用,招來(lái)其他用戶(hù)的強(qiáng)烈的抱怨,所以權(quán)限再次變更,只有create,update,delete,才需要權(quán)限保護(hù),query任何人都可以使用。
怎么辦?采用AuthProxy,使得InfoManager中的所有方法都被代理,加上了權(quán)限的判斷。當(dāng)然,最容易想到的辦法,就是在AuthProxy的intercept的方法中再做下判斷,如果代理的method是query,不需要權(quán)限驗(yàn)證。這么做,可以,但是一旦邏輯比較復(fù)雜的時(shí)候,intercept這個(gè)方法要做的事情會(huì)很多,邏輯會(huì)異常的復(fù)雜。
幸好,cglib還提供了CallbackFilter。使用CallbackFilter,可以明確表明,被代理的類(lèi)(InfoManager)中不同的方法,被哪個(gè)攔截器(interceptor)攔截。
AuthProxyFilter.java
public class AuthProxyFilter implements CallbackFilter {
private static final int AUTH_NEED = 0;
private static final int AUTH_NOT_NEED = 1;
/**
* <pre>
* 選擇使用的proxy
* 如果調(diào)用query函數(shù),則使用第二個(gè)proxy
* 否則,使用第一個(gè)proxy
* </pre>
*/
@Override
public int accept(Method method) {
if ("query".equals(method.getName())) {
return AUTH_NOT_NEED;
}
return AUTH_NEED;
}
}
這段代碼什么意思?其中的accept方法的意思是說(shuō),如果代理的方法是query(),那么使用第二個(gè)攔截器去攔截,如果代理的方法不是query(),那么使用第一個(gè)攔截器去攔截。所以我們只要再寫(xiě)一個(gè)攔截器,不做權(quán)限校驗(yàn)就行了。(其實(shí),cglib中的NoOp.INSTANCE就是一個(gè)空的攔截器,只要配置上這個(gè)就可以了。)
InfoManagerFactory.java--代碼修改如下:(配置不同的攔截器和filter)
public class InfoManagerFactory {
/**
* 創(chuàng)建不同權(quán)限要求的InfoManager
*
* @param auth
* @return
*/
public static InfoManager getSelectivityAuthInstance(AuthProxy auth) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(InfoManager.class);
enhancer.setCallbacks(new Callback[] { auth, NoOp.INSTANCE });
enhancer.setCallbackFilter(new AuthProxyFilter());
return (InfoManager) enhancer.create();
}
}
記住:setCallbacks中的攔截器(interceptor)的順序,一定要和
CallbackFilter里面指定的順序一致!!切忌。
Client.java
public class Client {
public static void main(String[] args) {
Client c = new Client();
c.selectivityAuthManager();
}
/**
* 模擬:沒(méi)有權(quán)限的會(huì)員,可以作查詢(xún)操作
*/
public void selectivityAuthManager() {
System.out.println("the loginer's name is not maurice,so have no permits do manager except do query operator
");
InfoManager authManager = InfoManagerFactory.getSelectivityAuthInstance(new AuthProxy("maurice1"));
doCRUD(authManager);
separatorLine();
}
/**
* 對(duì)Info做增加/更新/刪除/查詢(xún)操作
*
* @param manager
*/
private void doCRUD(InfoManager manager) {
manager.create();
manager.update();
manager.delete();
manager.query();
}
/**
* 加一個(gè)分隔行,用于區(qū)分
*/
private void separatorLine() {
System.out.println("################################");
}
}
此時(shí),對(duì)于query的權(quán)限校驗(yàn)已經(jīng)被去掉了。
通過(guò)一個(gè)模擬需求,簡(jiǎn)單介紹了cglib aop功能的使用。
CGlib應(yīng)用非常廣,在spring,hibernate等框架中,被大量的使用。
CGlib原理:
cglib神奇嗎?其實(shí)一旦了解cglib enhancer的原理,一切就真相大白了。
剛才在第二部分中,有個(gè)疑問(wèn):enhancer.create()到底返回了什么對(duì)象?
其實(shí)在剛才的例子中,cglib在代碼運(yùn)行期,動(dòng)態(tài)生成了InfoManager的子類(lèi),并且根據(jù)CallbackFilter的accept方法,覆寫(xiě)了InfoManager中的所有方法--去執(zhí)行相應(yīng)的MethodInterceptor的intercept方法。
有興趣的朋友可以看看我反編譯的InfoManager的子類(lèi),就可以很明白知道具體的實(shí)現(xiàn)了。(需要有耐心才可以)
InfoManager$$EnhancerByCGLIB$$de624598.jad
// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3)
// Source File Name: <generated>
package cn.eulic.codelab.cglib;
import java.lang.reflect.Method;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.*;
// Referenced classes of package cn.eulic.codelab.cglib:
// InfoManager
public class CGLIB.BIND_CALLBACKS extends InfoManager
implements Factory
{
static void CGLIB$STATICHOOK1()
{
Class class1;
ClassLoader classloader;
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
classloader = (class1 = Class.forName("cn.eulic.codelab.cglib.InfoManager$$EnhancerByCGLIB$$de624598")).getClassLoader();
classloader;
CGLIB$emptyArgs = new Object[0];
CGLIB$delete$0$Proxy = MethodProxy.create(classloader, (CGLIB$delete$0$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("delete", new Class[0])).getDeclaringClass(), class1, "()V", "delete", "CGLIB$delete$0");
CGLIB$create$1$Proxy = MethodProxy.create(classloader, (CGLIB$create$1$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("create", new Class[0])).getDeclaringClass(), class1, "()V", "create", "CGLIB$create$1");
CGLIB$query$2$Proxy = MethodProxy.create(classloader, (CGLIB$query$2$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("query", new Class[0])).getDeclaringClass(), class1, "()V", "query", "CGLIB$query$2");
CGLIB$update$3$Proxy = MethodProxy.create(classloader, (CGLIB$update$3$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("update", new Class[0])).getDeclaringClass(), class1, "()V", "update", "CGLIB$update$3");
CGLIB$finalize$4$Proxy = MethodProxy.create(classloader, (CGLIB$finalize$4$Method = Class.forName("java.lang.Object").getDeclaredMethod("finalize", new Class[0])).getDeclaringClass(), class1, "()V", "finalize", "CGLIB$finalize$4");
CGLIB$hashCode$5$Proxy = MethodProxy.create(classloader, (CGLIB$hashCode$5$Method = Class.forName("java.lang.Object").getDeclaredMethod("hashCode", new Class[0])).getDeclaringClass(), class1, "()I", "hashCode", "CGLIB$hashCode$5");
CGLIB$clone$6$Proxy = MethodProxy.create(classloader, (CGLIB$clone$6$Method = Class.forName("java.lang.Object").getDeclaredMethod("clone", new Class[0])).getDeclaringClass(), class1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$6");
CGLIB$equals$7$Proxy = MethodProxy.create(classloader, (CGLIB$equals$7$Method = Class.forName("java.lang.Object").getDeclaredMethod("equals", new Class[] {
Class.forName("java.lang.Object")
})).getDeclaringClass(), class1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$7");
CGLIB$toString$8$Proxy = MethodProxy.create(classloader, (CGLIB$toString$8$Method = Class.forName("java.lang.Object").getDeclaredMethod("toString", new Class[0])).getDeclaringClass(), class1, "()Ljava/lang/String;", "toString", "CGLIB$toString$8");
return;
}
final void CGLIB$delete$0()
{
super.delete();
}
public final void delete()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1
_L1:
JVM INSTR pop ;
CGLIB$BIND_CALLBACKS(this);
CGLIB$CALLBACK_0;
_L2:
JVM INSTR dup ;
JVM INSTR ifnull 37;
goto _L3 _L4
_L3:
break MISSING_BLOCK_LABEL_21;
_L4:
break MISSING_BLOCK_LABEL_37;
this;
CGLIB$delete$0$Method;
CGLIB$emptyArgs;
CGLIB$delete$0$Proxy;
intercept();
return;
super.delete();
return;
}
final void CGLIB$create$1()
{
super.create();
}
public final void create()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1
_L1:
JVM INSTR pop ;
CGLIB$BIND_CALLBACKS(this);
CGLIB$CALLBACK_0;
_L2:
JVM INSTR dup ;
JVM INSTR ifnull 37;
goto _L3 _L4
_L3:
break MISSING_BLOCK_LABEL_21;
_L4:
break MISSING_BLOCK_LABEL_37;
this;
CGLIB$create$1$Method;
CGLIB$emptyArgs;
CGLIB$create$1$Proxy;
intercept();
return;
super.create();
return;
}
final void CGLIB$query$2()
{
super.query();
}
public final void query()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1
_L1:
JVM INSTR pop ;
CGLIB$BIND_CALLBACKS(this);
CGLIB$CALLBACK_0;
_L2:
JVM INSTR dup ;
JVM INSTR ifnull 37;
goto _L3 _L4
_L3:
break MISSING_BLOCK_LABEL_21;
_L4:
break MISSING_BLOCK_LABEL_37;
this;
CGLIB$query$2$Method;
CGLIB$emptyArgs;
CGLIB$query$2$Proxy;
intercept();
return;
super.query();
return;
}
final void CGLIB$update$3()
{
super.update();
}
public final void update()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1
_L1:
JVM INSTR pop ;
CGLIB$BIND_CALLBACKS(this);
CGLIB$CALLBACK_0;
_L2:
JVM INSTR dup ;
JVM INSTR ifnull 37;
goto _L3 _L4
_L3:
break MISSING_BLOCK_LABEL_21;
_L4:
break MISSING_BLOCK_LABEL_37;
this;
CGLIB$update$3$Method;
CGLIB$emptyArgs;
CGLIB$update$3$Proxy;
intercept();
return;
super.update();
return;
}
final void CGLIB$finalize$4()
throws Throwable
{
super.finalize();
}
protected final void finalize()
throws Throwable
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1
_L1:
JVM INSTR pop ;
CGLIB$BIND_CALLBACKS(this);
CGLIB$CALLBACK_0;
_L2:
JVM INSTR dup ;
JVM INSTR ifnull 37;
goto _L3 _L4
_L3:
break MISSING_BLOCK_LABEL_21;
_L4:
break MISSING_BLOCK_LABEL_37;
this;
CGLIB$finalize$4$Method;
CGLIB$emptyArgs;
CGLIB$finalize$4$Proxy;
intercept();
return;
super.finalize();
return;
}
final int CGLIB$hashCode$5()
{
return super.hashCode();
}
public final int hashCode()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1
_L1:
JVM INSTR pop ;
CGLIB$BIND_CALLBACKS(this);
CGLIB$CALLBACK_0;
_L2:
JVM INSTR dup ;
JVM INSTR ifnull 52;
goto _L3 _L4
_L3:
this;
CGLIB$hashCode$5$Method;
CGLIB$emptyArgs;
CGLIB$hashCode$5$Proxy;
intercept();
JVM INSTR dup ;
JVM INSTR ifnonnull 45;
goto _L5 _L6
_L5:
JVM INSTR pop ;
0;
goto _L7
_L6:
(Number);
intValue();
_L7:
return;
_L4:
return super.hashCode();
}
final Object CGLIB$clone$6()
throws CloneNotSupportedException
{
return super.clone();
}
protected final Object clone()
throws CloneNotSupportedException
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1
_L1:
JVM INSTR pop ;
CGLIB$BIND_CALLBACKS(this);
CGLIB$CALLBACK_0;
_L2:
JVM INSTR dup ;
JVM INSTR ifnull 37;
goto _L3 _L4
_L3:
this;
CGLIB$clone$6$Method;
CGLIB$emptyArgs;
CGLIB$clone$6$Proxy;
intercept();
return;
_L4:
return super.clone();
}
final boolean CGLIB$equals$7(Object obj)
{
return super.equals(obj);
}
public final boolean equals(Object obj)
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1
_L1:
JVM INSTR pop ;
CGLIB$BIND_CALLBACKS(this);
CGLIB$CALLBACK_0;
_L2:
JVM INSTR dup ;
JVM INSTR ifnull 57;
goto _L3 _L4
_L3:
this;
CGLIB$equals$7$Method;
new Object[] {
obj
};
CGLIB$equals$7$Proxy;
intercept();
JVM INSTR dup ;
JVM INSTR ifnonnull 50;
goto _L5 _L6
_L5:
JVM INSTR pop ;
false;
goto _L7
_L6:
(Boolean);
booleanValue();
_L7:
return;
_L4:
return super.equals(obj);
}
final String CGLIB$toString$8()
{
return super.toString();
}
public final String toString()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0 != null) goto _L2; else goto _L1
_L1:
JVM INSTR pop ;
CGLIB$BIND_CALLBACKS(this);
CGLIB$CALLBACK_0;
_L2:
JVM INSTR dup ;
JVM INSTR ifnull 40;
goto _L3 _L4
_L3:
this;
CGLIB$toString$8$Method;
CGLIB$emptyArgs;
CGLIB$toString$8$Proxy;
intercept();
(String);
return;
_L4:
return super.toString();
}
public static MethodProxy CGLIB$findMethodProxy(Signature signature)
{
String s = signature.toString();
s;
s.hashCode();
JVM INSTR lookupswitch 9: default 200
// -1949253108: 92
// -1574182249: 104
// -1166709331: 116
// -508378822: 128
// -358764054: 140
// 598313209: 152
// 1826985398: 164
// 1913648695: 176
// 1984935277: 188;
goto _L1 _L2 _L3 _L4 _L5 _L6 _L7 _L8 _L9 _L10
_L2:
"update()V";
equals();
JVM INSTR ifeq 201;
goto _L11 _L12
_L12:
break MISSING_BLOCK_LABEL_201;
_L11:
return CGLIB$update$3$Proxy;
_L3:
"finalize()V";
equals();
JVM INSTR ifeq 201;
goto _L13 _L14
_L14:
break MISSING_BLOCK_LABEL_201;
_L13:
return CGLIB$finalize$4$Proxy;
_L4:
"query()V";
equals();
JVM INSTR ifeq 201;
goto _L15 _L16
_L16:
break MISSING_BLOCK_LABEL_201;
_L15:
return CGLIB$query$2$Proxy;
_L5:
"clone()Ljava/lang/Object;";
equals();
JVM INSTR ifeq 201;
goto _L17 _L18
_L18:
break MISSING_BLOCK_LABEL_201;
_L17:
return CGLIB$clone$6$Proxy;
_L6:
"delete()V";
equals();
JVM INSTR ifeq 201;
goto _L19 _L20
_L20:
break MISSING_BLOCK_LABEL_201;
_L19:
return CGLIB$delete$0$Proxy;
_L7:
"create()V";
equals();
JVM INSTR ifeq 201;
goto _L21 _L22
_L22:
break MISSING_BLOCK_LABEL_201;
_L21:
return CGLIB$create$1$Proxy;
_L8:
"equals(Ljava/lang/Object;)Z";
equals();
JVM INSTR ifeq 201;
goto _L23 _L24
_L24:
break MISSING_BLOCK_LABEL_201;
_L23:
return CGLIB$equals$7$Proxy;
_L9:
"toString()Ljava/lang/String;";
equals();
JVM INSTR ifeq 201;
goto _L25 _L26
_L26:
break MISSING_BLOCK_LABEL_201;
_L25:
return CGLIB$toString$8$Proxy;
_L10:
"hashCode()I";
equals();
JVM INSTR ifeq 201;
goto _L27 _L28
_L28:
break MISSING_BLOCK_LABEL_201;
_L27:
return CGLIB$hashCode$5$Proxy;
_L1:
JVM INSTR pop ;
return null;
}
public static void CGLIB$SET_THREAD_CALLBACKS(Callback acallback[])
{
CGLIB$THREAD_CALLBACKS.set(acallback);
}
public static void CGLIB$SET_STATIC_CALLBACKS(Callback acallback[])
{
CGLIB$STATIC_CALLBACKS = acallback;
}
private static final void CGLIB$BIND_CALLBACKS(Object obj)
{
CGLIB.STATIC_CALLBACKS static_callbacks = (CGLIB.STATIC_CALLBACKS)obj;
if(static_callbacks.CGLIB$BOUND) goto _L2; else goto _L1
_L1:
Object obj1;
static_callbacks.CGLIB$BOUND = true;
obj1 = CGLIB$THREAD_CALLBACKS.get();
obj1;
if(obj1 != null) goto _L4; else goto _L3
_L3:
JVM INSTR pop ;
CGLIB$STATIC_CALLBACKS;
if(CGLIB$STATIC_CALLBACKS != null) goto _L4; else goto _L5
_L5:
JVM INSTR pop ;
goto _L2
_L4:
(Callback[]);
static_callbacks;
JVM INSTR swap ;
0;
JVM INSTR aaload ;
(MethodInterceptor);
CGLIB$CALLBACK_0;
_L2:
}
public Object newInstance(Callback acallback[])
{
CGLIB$SET_THREAD_CALLBACKS(acallback);
CGLIB$SET_THREAD_CALLBACKS(null);
return new <init>();
}
public Object newInstance(Callback callback)
{
CGLIB$SET_THREAD_CALLBACKS(new Callback[] {
callback
});
CGLIB$SET_THREAD_CALLBACKS(null);
return new <init>();
}
public Object newInstance(Class aclass[], Object aobj[], Callback acallback[])
{
CGLIB$SET_THREAD_CALLBACKS(acallback);
JVM INSTR new #2 <Class InfoManager$$EnhancerByCGLIB$$de624598>;
JVM INSTR dup ;
aclass;
aclass.length;
JVM INSTR tableswitch 0 0: default 35
// 0 28;
goto _L1 _L2
_L2:
JVM INSTR pop ;
<init>();
goto _L3
_L1:
JVM INSTR pop ;
throw new IllegalArgumentException("Constructor not found");
_L3:
CGLIB$SET_THREAD_CALLBACKS(null);
return;
}
public Callback getCallback(int i)
{
CGLIB$BIND_CALLBACKS(this);
this;
i;
JVM INSTR tableswitch 0 0: default 30
// 0 24;
goto _L1 _L2
_L2:
CGLIB$CALLBACK_0;
goto _L3
_L1:
JVM INSTR pop ;
null;
_L3:
return;
}
public void setCallback(int i, Callback callback)
{
this;
callback;
i;
JVM INSTR tableswitch 0 0: default 29
// 0 20;
goto _L1 _L2
_L2:
(MethodInterceptor);
CGLIB$CALLBACK_0;
goto _L3
_L1:
JVM INSTR pop2 ;
_L3:
}
public Callback[] getCallbacks()
{
CGLIB$BIND_CALLBACKS(this);
this;
return (new Callback[] {
CGLIB$CALLBACK_0
});
}
public void setCallbacks(Callback acallback[])
{
this;
acallback;
JVM INSTR dup2 ;
0;
JVM INSTR aaload ;
(MethodInterceptor);
CGLIB$CALLBACK_0;
}
private boolean CGLIB$BOUND;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback CGLIB$STATIC_CALLBACKS[];
private MethodInterceptor CGLIB$CALLBACK_0;
private static final Method CGLIB$delete$0$Method;
private static final MethodProxy CGLIB$delete$0$Proxy;
private static final Object CGLIB$emptyArgs[];
private static final Method CGLIB$create$1$Method;
private static final MethodProxy CGLIB$create$1$Proxy;
private static final Method CGLIB$query$2$Method;
private static final MethodProxy CGLIB$query$2$Proxy;
private static final Method CGLIB$update$3$Method;
private static final MethodProxy CGLIB$update$3$Proxy;
private static final Method CGLIB$finalize$4$Method;
private static final MethodProxy CGLIB$finalize$4$Proxy;
private static final Method CGLIB$hashCode$5$Method;
private static final MethodProxy CGLIB$hashCode$5$Proxy;
private static final Method CGLIB$clone$6$Method;
private static final MethodProxy CGLIB$clone$6$Proxy;
private static final Method CGLIB$equals$7$Method;
private static final MethodProxy CGLIB$equals$7$Proxy;
private static final Method CGLIB$toString$8$Method;
private static final MethodProxy CGLIB$toString$8$Proxy;
static
{
CGLIB$STATICHOOK1();
}
public ()
{
CGLIB$BIND_CALLBACKS(this);
}
}
附件如下:
cglib sample