先通過demo演示效果,然后進行源碼分析
demo用Enhancer結(jié)合MethodInterceptor以及CallBackFilter完成
這里Enhancer類是CGLib中的一個字節(jié)碼增強器崇呵,它可以方便的對你想要處理的類進行擴展
1.demo
攔截器1
package cglib;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
//實現(xiàn)MethodInterceptor接口艘刚,定義方法的攔截器
@Override
public Object intercept(Object o, Method method, Object[] objects,
MethodProxy methodProxy) throws Throwable {
System.out.println("pre");
//通過代理類調(diào)用父類中的方法,即實體類方法
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("after");
return result;
}
}
攔截器2
package cglib;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy2 implements MethodInterceptor {
//實現(xiàn)MethodInterceptor接口胳螟,定義方法的攔截器
@Override
public Object intercept(Object o, Method method, Object[] objects,
MethodProxy methodProxy) throws Throwable {
System.out.println("pre1");
//通過代理類調(diào)用父類中的方法,即實體類方法
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("after1");
return result;
}
}
回調(diào)過濾器CallbackFilter
package cglib;
import net.sf.cglib.proxy.CallbackFilter;
import java.lang.reflect.Method;
public class filter implements CallbackFilter {
@Override
public int accept(Method method) {
if(method.getName().equals("toString")) {
return 1;
}
return 0;
}
}
測試類
package cglib;
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
public class CglibLearn {
//定義委托類姐霍,可以不是接口
static class serviceImpl {
void say()
{
System.out.println("say");
}
}
public static Object getProxyInstance(Object realSubject) {
Enhancer enhancer = new Enhancer();
//需要創(chuàng)建子類的類,即定義委托類
enhancer.setSuperclass(realSubject.getClass());
//設(shè)置兩個CallBack以及CallbackFilter
Callback[] callbacks=new Callback[2];
callbacks[0]=new CglibProxy();
callbacks[1]=new CglibProxy2();
enhancer.setCallbacks(callbacks);
enhancer.setCallbackFilter(new filter());
//通過字節(jié)碼技術(shù)動態(tài)創(chuàng)建子類實例
return enhancer.create();
}
public static void main(String[] args) {
//將sam,class文件寫到硬盤
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, ".//");
//通過生成子類的方式創(chuàng)建代理類
serviceImpl impl = (serviceImpl)getProxyInstance(new serviceImpl());
impl.say();
impl.toString();
}
}
輸出,自己想想就知道
2.源碼分析
看源碼之前蕊玷,最好先了解下callBack和callBackFilter是有什么作用应媚,再看會帶著問題看
直接進測試類的enhancer.create();探究這個代理對象是怎么生成的,下面按照幾個注意的環(huán)節(jié)來講,會經(jīng)歷整個創(chuàng)建過程
2.1根據(jù)代理類的配置作為組合Key
net.sf.cglib.proxy.Enhancer#create()
net.sf.cglib.proxy.Enhancer#createHelper()
private Object createHelper() {
//進行有效性驗證鲁冯,比如有多個callBack卻沒有callBackFilter
validate();
if (superclass != null) {
setNamePrefix(superclass.getName());
} else if (interfaces != null) {
setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
}
//先根據(jù)KEY_FACTORY 以當(dāng)前代理類的配置信息 生成一個組合Key拷沸,再利用這個組合Key,進行create
return super.create(KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null,
ReflectUtils.getNames(interfaces),
filter,
callbackTypes,
useFactory,
interceptDuringConstruction,
serialVersionUID));
}
這里注意
KEY_FACTORY 就是前兩節(jié)講到的根據(jù)KeyFactory薯演,完成multi-value的一個Key
可以理解成這里如果代理類的配置撞芍,作為Key,一樣的換就能利用緩存了涣仿,后面會講到利用的緩存
private static final EnhancerKey KEY_FACTORY =
(EnhancerKey)KeyFactory.create(EnhancerKey.class);
public interface EnhancerKey {
public Object newInstance(String type,
String[] interfaces,
CallbackFilter filter,
Type[] callbackTypes,
boolean useFactory,
boolean interceptDuringConstruction,
Long serialVersionUID);
}
2.2 利用緩存完成根據(jù)Key獲取Class信息勤庐,進而生成代理對象
這一塊代碼比較簡單,和之前jdk動態(tài)代理利用的緩存差不多,在KeyFactory那一節(jié)也講過好港,還是列出來就行,看注釋就夠了
protected Object create(Object key) {
try {
//需要緩存的類
Class gen = null;
synchronized (source) {
ClassLoader loader = getClassLoader();
Map cache2 = null;
//根據(jù)來源區(qū)分,根據(jù)classLoader進行一級緩存
cache2 = (Map)source.cache.get(loader);
if (cache2 == null) {
cache2 = new HashMap();
cache2.put(NAME_KEY, new HashSet());
source.cache.put(loader, cache2);
} else if (useCache) {
//用緩存
Reference ref = (Reference)cache2.get(key);
gen = (Class) (( ref == null ) ? null : ref.get());
}
if (gen == null) {
Object save = CURRENT.get();
CURRENT.set(this);
try {
this.key = key;
if (attemptLoad) {
try {
gen = loader.loadClass(getClassName());
} catch (ClassNotFoundException e) {
// ignore
}
}
if (gen == null) {
//結(jié)合生成策略愉镰,得到類的字節(jié)碼
byte[] b = strategy.generate(this);
String className = ClassNameReader.getClassName(new ClassReader(b));
getClassNameCache(loader).add(className);
//根據(jù)字節(jié)碼生成類
gen = ReflectUtils.defineClass(className, b, loader);
}
if (useCache) {
//根據(jù)傳入的key,進行二級緩存
cache2.put(key, new WeakReference(gen));
}
//根據(jù)類钧汹,生成實例
return firstInstance(gen);
} finally {
CURRENT.set(save);
}
}
}
return firstInstance(gen);
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (Exception e) {
throw new CodeGenerationException(e);
}
}
可以看出來丈探,關(guān)注點集中在代理類的生成,即
byte[] b = strategy.generate(this);
2.3.代理類的生成
繼續(xù)跟進
net.sf.cglib.core.GeneratorStrategy#generate
net.sf.cglib.core.DefaultGeneratorStrategy#generate
net.sf.cglib.core.ClassGenerator#generateClass
net.sf.cglib.proxy.Enhancer#generateClass
最終就是利用Enhancer來生成代理類,下面有詳細(xì)的注釋
public void generateClass(ClassVisitor v) throws Exception {
Class sc = (superclass == null) ? Object.class : superclass;
if (TypeUtils.isFinal(sc.getModifiers()))
throw new IllegalArgumentException("Cannot subclass final class " + sc);
List constructors = new ArrayList(Arrays.asList(sc.getDeclaredConstructors()));
filterConstructors(sc, constructors);
// Order is very important: must add superclass, then
// its superclass chain, then each interface and
// its superinterfaces.
List actualMethods = new ArrayList();
List interfaceMethods = new ArrayList();
final Set forcePublic = new HashSet();
/*
根據(jù)規(guī)定的父類,生成需要的方法拔莱,參見 CglibLearn$serviceImpl$$EnhancerByCGLIB$$81852b18.class
actualMethods記錄所有經(jīng)過過濾的方法
interfaceMethods和forcePublic的size都為0
*/
getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
for(int i=0;i<actualMethods.size();i++) {
System.out.println("actualMethods is " + actualMethods.get(i));
}
/*
把actualMethods中碗降,非abstract,非native,非synchronized方法的修飾符全部變成final
將轉(zhuǎn)化后的方法信息MethodInfo列表 記錄在methods中
*/
List methods = CollectionUtils.transform(actualMethods, new Transformer() {
public Object transform(Object value) {
Method method = (Method)value;
int modifiers = Constants.ACC_FINAL
| (method.getModifiers()
& ~Constants.ACC_ABSTRACT
& ~Constants.ACC_NATIVE
& ~Constants.ACC_SYNCHRONIZED);
if (forcePublic.contains(MethodWrapper.create(method))) {
modifiers = (modifiers & ~Constants.ACC_PROTECTED) | Constants.ACC_PUBLIC;
}
return ReflectUtils.getMethodInfo(method, modifiers);
}
});
ClassEmitter e = new ClassEmitter(v);
//開始生成代理類 繼承指定的superClass
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);
//將構(gòu)造函數(shù)信息 記錄在 constructorInfo 中
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);
}
//聲明field,是定義的callbackType,設(shè)置了幾個callBack塘秦,這里就有幾個field,名字為CGLIB$CALLBACK_xxx(為id)
for (int i = 0; i < callbackTypes.length; i++) {
e.declare_field(Constants.ACC_PRIVATE, getCallbackField(i), callbackTypes[i], null);
}
//根據(jù)methods,actualMethods生成方法讼渊,完成callBack,callBackFilter的處理
emitMethods(e, methods, actualMethods);
//生成構(gòu)造函數(shù)
emitConstructors(e, constructorInfo);
//這幾個暫時不清楚
emitSetThreadCallbacks(e);
emitSetStaticCallbacks(e);
emitBindCallbacks(e);
if (useFactory) {
int[] keys = getCallbackKeys();
emitNewInstanceCallbacks(e);
emitNewInstanceCallback(e);
emitNewInstanceMultiarg(e, constructorInfo);
emitGetCallback(e, keys);
emitSetCallback(e, keys);
emitGetCallbacks(e);
emitSetCallbacks(e);
}
e.end_class();
}
備注尊剔,上面利用asm完成類的生成,主要步驟如下
1.getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
這個方法就是遞歸的將superClass的父類爪幻,父接口的函數(shù)全部記錄在method中,
然后過濾掉原有類的static方法,private方法,和superClass位于不同包的類中的方法(不知道何時會出現(xiàn)這種情況???),以及final方法
獲取须误,并且過濾完之后挨稿,剩下的方法是
void cglib.CglibLearn$serviceImpl.say()
protected void java.lang.Object.finalize() throws java.lang.Throwable
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException
2.emitMethods
這個函數(shù)是用來生成代理類里面的methods,非常重要京痢,列出源碼如下
/*
methods 是方法的信息列表, 每一個類型都是MethodInfo
actualMethods 是真實的方法, 每一個類型都是Method
*/
private void emitMethods(final ClassEmitter ce, List methods, List actualMethods) {
/*
根據(jù)callbackTypes得到對應(yīng)的generator,跟進去看
比如callbackType是MethodInterceptor.class,對應(yīng)的generator就是MethodInterceptorGenerator.INSTANCE
*/
CallbackGenerator[] generators = CallbackInfo.getGenerators(callbackTypes);
Map groups = new HashMap();
final Map indexes = new HashMap();
final Map originalModifiers = new HashMap();
final Map positions = CollectionUtils.getIndexMap(methods);
final Map declToBridge = new HashMap();
Iterator it1 = methods.iterator();
Iterator it2 = (actualMethods != null) ? actualMethods.iterator() : null;
while (it1.hasNext()) {
MethodInfo method = (MethodInfo)it1.next();
Method actualMethod = (it2 != null) ? (Method)it2.next() : null;
/*
根據(jù)定義的callBackFilter的accept值奶甘,判斷由哪一個callBack來過濾當(dāng)前方法
filter這里默認(rèn)是net.sf.cglib.proxy.Enhancer.ALL_ZERO,即accept永遠返回0
*/
int index = filter.accept(actualMethod);
if (index >= callbackTypes.length) {
throw new IllegalArgumentException("Callback filter returned an index that is too large: " + index);
}
originalModifiers.put(method, new Integer((actualMethod != null) ? actualMethod.getModifiers() : method.getModifiers()));
//通過indexes這個map記錄每個map該由第幾個callBack來處理
indexes.put(method, new Integer(index));
//讓這個callBack對應(yīng)的generator 記錄下來它要處理這個method
List group = (List)groups.get(generators[index]);
if (group == null) {
groups.put(generators[index], group = new ArrayList(methods.size()));
}
group.add(method);
// Optimization: build up a map of Class -> bridge methods in class
// so that we can look up all the bridge methods in one pass for a class.
if (TypeUtils.isBridge(actualMethod.getModifiers())) {
Set bridges = (Set)declToBridge.get(actualMethod.getDeclaringClass());
if (bridges == null) {
bridges = new HashSet();
declToBridge.put(actualMethod.getDeclaringClass(), bridges);
}
bridges.add(method.getSignature());
}
}
final Map bridgeToTarget = new BridgeMethodResolver(declToBridge).resolveAll();
Set seenGen = new HashSet();
CodeEmitter se = ce.getStaticHook();
se.new_instance(THREAD_LOCAL);
se.dup();
se.invoke_constructor(THREAD_LOCAL, CSTRUCT_NULL);
se.putfield(THREAD_CALLBACKS_FIELD);
final Object[] state = new Object[1];
//下面context定義了如何根據(jù)callBack信息,來進行代碼生成
CallbackGenerator.Context context = new CallbackGenerator.Context() {
public ClassLoader getClassLoader() {
return Enhancer.this.getClassLoader();
}
public int getOriginalModifiers(MethodInfo method) {
return ((Integer)originalModifiers.get(method)).intValue();
}
//根據(jù)method判斷對應(yīng)的callBack下標(biāo)
public int getIndex(MethodInfo method) {
return ((Integer)indexes.get(method)).intValue();
}
/*
根據(jù)下標(biāo)讓當(dāng)前method生成“調(diào)用對應(yīng)callBack”的代碼
這也表現(xiàn)出來一個method只有一個callBack
*/
public void emitCallback(CodeEmitter e, int index) {
emitCurrentCallback(e, index);
}
public Signature getImplSignature(MethodInfo method) {
return rename(method.getSignature(), ((Integer)positions.get(method)).intValue());
}
public void emitInvoke(CodeEmitter e, MethodInfo method) {
// If this is a bridge and we know the target was called from invokespecial,
// then we need to invoke_virtual w/ the bridge target instead of doing
// a super, because super may itself be using super, which would bypass
// any proxies on the target.
Signature bridgeTarget = (Signature)bridgeToTarget.get(method.getSignature());
if (bridgeTarget != null) {
// TODO: this assumes that the target has wider or the same type
// parameters than the current.
// In reality this should always be true because otherwise we wouldn't
// have had a bridge doing an invokespecial.
// If it isn't true, we would need to checkcast each argument
// against the target's argument types
e.invoke_virtual_this(bridgeTarget);
Type retType = method.getSignature().getReturnType();
// Not necessary to cast if the target & bridge have
// the same return type.
// (This conveniently includes void and primitive types,
// which would fail if casted. It's not possible to
// covariant from boxed to unbox (or vice versa), so no having
// to box/unbox for bridges).
// TODO: It also isn't necessary to checkcast if the return is
// assignable from the target. (This would happen if a subclass
// used covariant returns to narrow the return type within a bridge
// method.)
if (!retType.equals(bridgeTarget.getReturnType())) {
e.checkcast(retType);
}
} else {
e.super_invoke(method.getSignature());
}
}
public CodeEmitter beginMethod(ClassEmitter ce, MethodInfo method) {
CodeEmitter e = EmitUtils.begin_method(ce, method);
if (!interceptDuringConstruction &&
!TypeUtils.isAbstract(method.getModifiers())) {
Label constructed = e.make_label();
e.load_this();
e.getfield(CONSTRUCTED_FIELD);
e.if_jump(e.NE, constructed);
e.load_this();
e.load_args();
e.super_invoke();
e.return_value();
e.mark(constructed);
}
return e;
}
};
for (int i = 0; i < callbackTypes.length; i++) {
CallbackGenerator gen = generators[i];
if (!seenGen.contains(gen)) {
seenGen.add(gen);
/*
每個callBack對應(yīng)的generator要處理的列表為fmethods
下面將每個method對應(yīng)的callBack調(diào)用關(guān)系祭椰,生成代碼
*/
final List fmethods = (List)groups.get(gen);
if (fmethods != null) {
try {
gen.generate(ce, context, fmethods);
gen.generateStatic(se, context, fmethods);
} catch (RuntimeException x) {
throw x;
} catch (Exception x) {
throw new CodeGenerationException(x);
}
}
}
}
se.return_value();
se.end_method();
}
這里的主要工作如下
int index = filter.accept(actualMethod); 這里是判斷當(dāng)前method是由哪一個callBack來處理
...
定義如何根據(jù)callBack信息臭家,來進行代碼生成
CallbackGenerator.Context context = new CallbackGenerator.Context(){xxx}
...
每個callBack對應(yīng)的generator要處理的列表為fmethods
下面將每個method對應(yīng)的callBack調(diào)用關(guān)系疲陕,生成代碼
final List fmethods = (List)groups.get(gen);
2.4.代理類的結(jié)果
本地生成了文件
其中,CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b文件的細(xì)節(jié)在intellij并沒有顯示完全钉赁,用
http://www.javadecompilers.com/result 去decompile一下鸭轮,可以看到細(xì)節(jié),一定要展示出來,方便理解代理類創(chuàng)建的過程
/*
* Decompiled with CFR 0_118.
*
* Could not load the following classes:
* cglib.CglibLearn
* cglib.CglibLearn$serviceImpl
* net.sf.cglib.core.ReflectUtils
* net.sf.cglib.core.Signature
* net.sf.cglib.proxy.Callback
* net.sf.cglib.proxy.Factory
* net.sf.cglib.proxy.MethodInterceptor
* net.sf.cglib.proxy.MethodProxy
*/
package cglib;
import cglib.CglibLearn;
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 CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b
extends CglibLearn.serviceImpl
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$say$0$Method;
private static final MethodProxy CGLIB$say$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$finalize$1$Method;
private static final MethodProxy CGLIB$finalize$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 class_ = Class.forName("cglib.CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b");
Class class_2 = Class.forName("java.lang.Object");
Method[] arrmethod = ReflectUtils.findMethods((String[])new String[]{"finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (Method[])class_2.getDeclaredMethods());
CGLIB$finalize$1$Method = arrmethod[0];
CGLIB$finalize$1$Proxy = MethodProxy.create(class_2, class_, (String)"()V", (String)"finalize", (String)"CGLIB$finalize$1");
CGLIB$equals$2$Method = arrmethod[1];
CGLIB$equals$2$Proxy = MethodProxy.create(class_2, class_, (String)"(Ljava/lang/Object;)Z", (String)"equals", (String)"CGLIB$equals$2");
CGLIB$toString$3$Method = arrmethod[2];
CGLIB$toString$3$Proxy = MethodProxy.create(class_2, class_, (String)"()Ljava/lang/String;", (String)"toString", (String)"CGLIB$toString$3");
CGLIB$hashCode$4$Method = arrmethod[3];
CGLIB$hashCode$4$Proxy = MethodProxy.create(class_2, class_, (String)"()I", (String)"hashCode", (String)"CGLIB$hashCode$4");
CGLIB$clone$5$Method = arrmethod[4];
CGLIB$clone$5$Proxy = MethodProxy.create(class_2, class_, (String)"()Ljava/lang/Object;", (String)"clone", (String)"CGLIB$clone$5");
class_2 = Class.forName("cglib.CglibLearn$serviceImpl");
CGLIB$say$0$Method = ReflectUtils.findMethods((String[])new String[]{"say", "()V"}, (Method[])class_2.getDeclaredMethods())[0];
CGLIB$say$0$Proxy = MethodProxy.create(class_2, class_, (String)"()V", (String)"say", (String)"CGLIB$say$0");
}
final void CGLIB$say$0() {
super.say();
}
final void say() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
Object object = methodInterceptor.intercept((Object)this, CGLIB$say$0$Method, CGLIB$emptyArgs, CGLIB$say$0$Proxy);
return;
}
super.say();
}
final void CGLIB$finalize$1() throws Throwable {
super.finalize();
}
protected final void finalize() throws Throwable {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
Object object = methodInterceptor.intercept((Object)this, CGLIB$finalize$1$Method, CGLIB$emptyArgs, CGLIB$finalize$1$Proxy);
return;
}
super.finalize();
}
final boolean CGLIB$equals$2(Object object) {
return super.equals(object);
}
public final boolean equals(Object object) {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
Object object2 = methodInterceptor.intercept((Object)this, CGLIB$equals$2$Method, new Object[]{object}, CGLIB$equals$2$Proxy);
return object2 == null ? false : (Boolean)object2;
}
return super.equals(object);
}
final String CGLIB$toString$3() {
return super.toString();
}
public final String toString() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_1;
if (methodInterceptor == null) {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_1;
}
if (methodInterceptor != null) {
return (String)methodInterceptor.intercept((Object)this, CGLIB$toString$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy);
}
return super.toString();
}
final int CGLIB$hashCode$4() {
return super.hashCode();
}
public final int hashCode() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
Object object = methodInterceptor.intercept((Object)this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);
return object == null ? 0 : ((Number)object).intValue();
}
return super.hashCode();
}
final Object CGLIB$clone$5() throws CloneNotSupportedException {
return super.clone();
}
protected final Object clone() throws CloneNotSupportedException {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
return methodInterceptor.intercept((Object)this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy);
}
return super.clone();
}
public static MethodProxy CGLIB$findMethodProxy(Signature signature) {
String string = signature.toString();
switch (string.hashCode()) {
case -1574182249: {
if (!string.equals("finalize()V")) break;
return CGLIB$finalize$1$Proxy;
}
case -909388886: {
if (!string.equals("say()V")) break;
return CGLIB$say$0$Proxy;
}
case -508378822: {
if (!string.equals("clone()Ljava/lang/Object;")) break;
return CGLIB$clone$5$Proxy;
}
case 1826985398: {
if (!string.equals("equals(Ljava/lang/Object;)Z")) break;
return CGLIB$equals$2$Proxy;
}
case 1913648695: {
if (!string.equals("toString()Ljava/lang/String;")) break;
return CGLIB$toString$3$Proxy;
}
case 1984935277: {
if (!string.equals("hashCode()I")) break;
return CGLIB$hashCode$4$Proxy;
}
}
return null;
}
public CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b() {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b = this;
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b);
}
public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] arrcallback) {
CGLIB$THREAD_CALLBACKS.set(arrcallback);
}
public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] arrcallback) {
CGLIB$STATIC_CALLBACKS = arrcallback;
}
private static final void CGLIB$BIND_CALLBACKS(Object object) {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b = (CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b)((Object)object);
if (!cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BOUND) {
cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BOUND = true;
Object t = CGLIB$THREAD_CALLBACKS.get();
if (t != null || (v312 = CGLIB$STATIC_CALLBACKS) != null) {
Callback[] arrcallback = (Callback[])t;
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b2 = cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b;
cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b2.CGLIB$CALLBACK_1 = (MethodInterceptor)arrcallback[1];
cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b2.CGLIB$CALLBACK_0 = (MethodInterceptor)arrcallback[0];
}
}
}
public Object newInstance(Callback[] arrcallback) {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$SET_THREAD_CALLBACKS(arrcallback);
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$SET_THREAD_CALLBACKS(null);
return new CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b();
}
public Object newInstance(Callback callback) {
throw new IllegalStateException("More than one callback object required");
}
/*
* Unable to fully structure code
* Enabled aggressive block sorting
* Lifted jumps to return sites
*/
public Object newInstance(Class[] var1_1, Object[] var2_2, Callback[] var3_3) {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$SET_THREAD_CALLBACKS(var3_3);
switch (var1_1.length) {
case 0: {
** break;
}
}
throw new IllegalArgumentException("Constructor not found");
lbl6: // 1 sources:
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$SET_THREAD_CALLBACKS(null);
return new CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b();
}
public Callback getCallback(int n) {
MethodInterceptor methodInterceptor;
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this);
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b = this;
switch (n) {
case 0: {
methodInterceptor = cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$CALLBACK_0;
break;
}
case 1: {
methodInterceptor = cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$CALLBACK_1;
break;
}
default: {
methodInterceptor = null;
}
}
return methodInterceptor;
}
public void setCallback(int n, Callback callback) {
switch (n) {
case 0: {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)callback;
break;
}
case 1: {
this.CGLIB$CALLBACK_1 = (MethodInterceptor)callback;
break;
}
}
}
public Callback[] getCallbacks() {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$BIND_CALLBACKS((Object)this);
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b = this;
return new Callback[]{this.CGLIB$CALLBACK_0, this.CGLIB$CALLBACK_1};
}
public void setCallbacks(Callback[] arrcallback) {
Callback[] arrcallback2 = arrcallback;
this.CGLIB$CALLBACK_0 = (MethodInterceptor)arrcallback2[0];
Callback[] arrcallback3 = arrcallback2;
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b cglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b = this;
this.CGLIB$CALLBACK_1 = (MethodInterceptor)arrcallback2[1];
}
static {
CglibLearn$serviceImpl$$EnhancerByCGLIB$$4e65f4b.CGLIB$STATICHOOK1();
}
}
3.測試類的結(jié)果分析
自己的demo中
cglib.CglibProxy#intercept和cglib.CglibProxy2#intercept是如何工作的橄霉,即調(diào)用
impl.say();的時候
攔截器是如何攔截的
參照上面得到的decompile文件
final void say() {
MethodInterceptor methodInterceptor = this.CGLIB$CALLBACK_0;
if (methodInterceptor == null) {
CGLIB$BIND_CALLBACKS(this);
methodInterceptor = this.CGLIB$CALLBACK_0;
}
if (methodInterceptor != null) {
methodInterceptor.intercept(this, CGLIB$say$0$Method, CGLIB$emptyArgs, CGLIB$say$0$Proxy);
} else {
say();
}
}
很容易看出來了,
另外比較一下
這里就是CGLIB$CALLBACK_1了邑蒋,這個是怎么辦到的?
其實在之前講net.sf.cglib.proxy.Enhancer#emitMethods時候就說了
net.sf.cglib.proxy.CallbackGenerator.Context#getIndex
配合net.sf.cglib.proxy.MethodInterceptorGenerator#generate里面
context.emitCallback(e, context.getIndex(method));
完成了每個method知道自己對應(yīng)的callBack是第幾個
另外姓蜂,攔截器攔截時,
Object result = methodProxy.invokeSuper(o, objects);
invokeSuper是干嗎的
這在下一節(jié)FastClass會講
4.思考
4.1 CallbackFilter 和 CallBack有什么關(guān)系
一個method只能有一個CallBack(不定義也會有默認(rèn)的)
CallBackFilter就是完成一個mapping的過程医吊,比如
a,b method 用 A callBack
c,d method 用 B callBack
源碼里也有體現(xiàn)出來一個method對應(yīng)一個callBack
4.2 method與callBack之間的對應(yīng)的關(guān)系是如何實現(xiàn)的
net.sf.cglib.proxy.Enhancer#emitMethods中
每個method通過 int index = filter.accept(actualMethod); 知道當(dāng)前method由第幾個callBack處理
然后由net.sf.cglib.proxy.MethodInterceptorGenerator#generate
context.emitCallback(e, context.getIndex(method));
將這種對應(yīng)關(guān)系寫到類中去
4.3 Enhancer如何根據(jù)callBack,callBackFilter完成代理類class文件的定義
net.sf.cglib.proxy.Enhancer#generateClass
主要是
net.sf.cglib.proxy.Enhancer#getMethods(java.lang.Class, java.lang.Class[], java.util.List, java.util.List, java.util.Set)
net.sf.cglib.proxy.Enhancer#emitMethods
4.4 與jdk動態(tài)代理區(qū)別
這里cglib底層是用的asm钱慢,而jdk動態(tài)代理沒有
4.5 Enhancer的"enhance"體現(xiàn)在哪
個人理解,可能并不準(zhǔn)確
1.完成callBack以及callBackFilter等的aop處理
2.完成代理類say()的調(diào)用 轉(zhuǎn)發(fā)給 方法代理即CGLIB$say$0$Proxy
methodInterceptor.intercept(this, CGLIB$say$0$Method, CGLIB$emptyArgs, CGLIB$say$0$Proxy);
//其中
CGLIB$say$0$Proxy = MethodProxy.create(cls2, cls, "()V", "say", "CGLIB$say$0");
最終將cls2的say方法轉(zhuǎn)發(fā)給cls的CGLIB$say$0方法(并不是上文列出來的CGLIB$say$0)卿堂,這個和fastClass相關(guān)束莫,下一節(jié)再講。
4.6 CGLIB$STATICHOOK1()作用
創(chuàng)建各種方法代理即MethodProxy,在下一節(jié)和fastClass一起講
5.備注
net.sf.cglib.proxy.Enhancer#generateClass還有一些emit其他細(xì)節(jié)草描,目前沒有涉及到览绿,沒有看
6.問題
findMethodProxy作用是啥,沒有看到調(diào)用
7.refer
http://javadox.com/cglib/cglib/2.2/net/sf/cglib/proxy/Enhancer.html#generateClass(org.objectweb.asm.ClassVisitor)
http://cglib.sourceforge.net/apidocs/
http://www.cnblogs.com/cruze/p/3865180.html