最近读了下cglib 的源代码,分析了cglib 通过字节码生成的代理类。就用cglib源代码包中的例子吧.
1.首先eclipse中开启debug模式,如图
例子的代码如下
public static void main(String args[]) {
Bean bean = (Bean)newInstance(Bean.class);
bean.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
}
}
);
bean.setSampleProperty("TEST");
}
转入newInstance方法中
public static Object newInstance(Class clazz) {
try {
Beans interceptor = new Beans();
Enhancer e = new Enhancer();
e.setSuperclass(clazz);
e.setCallback(interceptor);
Object bean = e.create();
interceptor.propertySupport = new PropertyChangeSupport(bean);
return bean;
} catch (Throwable e) {
e.printStackTrace();
throw new Error(e.getMessage());
}
}
Enhancer 类中主要的几个配置参数,也是cglib代理的几个配置参数
( 1 )
private Class[] interfaces;
private CallbackFilter filter;
private Callback[] callbacks;
private Type[] callbackTypes;
private boolean classOnly;
private Class superclass;
private Class[] argumentTypes;
private Object[] arguments;
private boolean useFactory = true;
private Long serialVersionUID;
private boolean interceptDuringConstruction = true;
在Enhancer类中有个KEY_FACTORY的属性
private static final EnhancerKey KEY_FACTORY = (EnhancerKey) KeyFactory.create(EnhancerKey.class);
此行代码会自动生成 Enhancer 类的 内部接口 EnhancerKey 的实现类
public interface EnhancerKey {
public Object newInstance( String type, String[] interfaces, CallbackFilter filter, Type[] callbackTypes, boolean useFactory, boolean interceptDuringConstruction, Long serialVersionUID );
}
反编译.class 文件的内容如下, 备注: 有些代码无法反编译,我参照.asm文件 重新改写了一下
package net.sf.cglib.proxy;
import net.sf.cglib.core.KeyFactory;
import org.objectweb.asm.Type;
public class Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72 extends KeyFactory implements Enhancer.EnhancerKey {
private final String FIELD_0;
private final String[] FIELD_1;
private final CallbackFilter FIELD_2;
private final Type[] FIELD_3;
private final boolean FIELD_4;
private final boolean FIELD_5;
private final Long FIELD_6;
public Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72() {
/** 以下在字节码指令中并没用赋值, 如果不赋值的话在eclipse的编译器中会报错,可能是final 字段在编译级别做了限制,在Jvm的指令中并没有啥实质的作用.*/
this.FIELD_0 = null;
this.FIELD_1 = null;
this.FIELD_2 = null;
this.FIELD_3 = null;
this.FIELD_4 = false;
this.FIELD_5 = false;
this.FIELD_6 = 0L;
}
public Object newInstance(String paramString, String[] paramArrayOfString, CallbackFilter paramCallbackFilter, Type[] paramArrayOfType, boolean paramBoolean1, boolean paramBoolean2, Long paramLong) {
return new Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72(paramString, paramArrayOfString, paramCallbackFilter, paramArrayOfType, paramBoolean1, paramBoolean2, paramLong);
}
public Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72(String paramString, String[] paramArrayOfString, CallbackFilter paramCallbackFilter, Type[] paramArrayOfType, boolean paramBoolean1, boolean paramBoolean2, Long paramLong) {
this.FIELD_0 = paramString;
this.FIELD_1 = paramArrayOfString;
this.FIELD_2 = paramCallbackFilter;
this.FIELD_3 = paramArrayOfType;
this.FIELD_4 = paramBoolean1;
this.FIELD_5 = paramBoolean2;
this.FIELD_6 = paramLong;
}
public int hashCode() {
// 根据 KeyFactory类的 PRIMES数组得来的
int result = 8095873;
result += (FIELD_0 != null ? FIELD_0.hashCode() * 69403 : 0);
if(FIELD_1 != null) {
if(FIELD_1.length > 0) {
String s0 = FIELD_1[0];
result += (s0.hashCode() * 69403);
}
}
result += (FIELD_2 != null ? FIELD_2.hashCode() * 69403 : 0);
if(FIELD_3 != null) {
if(FIELD_3.length > 0) {
Type t0 = FIELD_3[0];
result += t0.hashCode() * 69403;
}
}
result += FIELD_4 ? 1 : 0;
result += FIELD_5 ? 1 : 0;
result += FIELD_6.hashCode() * 69403;
return result;
}
public boolean equals(Object paramObject) {
// 略
}
public String toString() {
// 略
}
}
在回到 Object bean = e.create();这行代码 , 之后会转到这
private Object createHelper() {
validate();
if (superclass != null) {
setNamePrefix(superclass.getName());
} else if (interfaces != null) {
setNamePrefix(interfaces[ReflectUtils.findPackageProtected(interfaces)].getName());
}
return super.create(KEY_FACTORY.newInstance((superclass != null) ? superclass.getName() : null, ReflectUtils.getNames(interfaces), filter, callbackTypes, useFactory, interceptDuringConstruction, serialVersionUID));
}
KEY_FACTORY.newInstance 这创建一个 Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72 这个对象的实例,
主要是作用是存储Enhancer 类的几个参数 上面 ( 1 )
之后转到 AbstractClassGenerator 类的create方法 如下代码
protected Object create(Object key) {
try {
Class gen = null;
synchronized (source) {
ClassLoader loader = getClassLoader();
ProtectionDomain protectionDomain = getProtectionDomain();
Map cache2 = null;
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) {
byte[] b = strategy.generate(this);
String className = ClassNameReader.getClassName(new ClassReader(b));
getClassNameCache(loader).add(className);
if (protectionDomain == null) {
gen = ReflectUtils.defineClass(className, b, loader);
} else {
gen = ReflectUtils.defineClass(className, b, loader, protectionDomain);
}
}
if (useCache) {
cache2.put(key, new WeakReference(gen));
}
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);
}
}
标红的代码
byte[] b = strategy.generate(this); 最终会转到 Enhancer 类的 generateClass方法 是创建代理的主要方法, 具体代码如下
public void generateClass(ClassVisitor v) throws Exception {
// superclass 是要代理的类
Class sc = (superclass == null) ? Object.class : superclass;
// 如果是 final 修饰的方法 抛出异常
if (TypeUtils.isFinal(sc.getModifiers()))
throw new IllegalArgumentException("Cannot subclass final class " + sc.getName());
// 构造方法
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();
// 获取代理类的所有方法 和 代理类所实现接口的所有方法
getMethods(sc, interfaces, actualMethods, interfaceMethods, forcePublic);
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);
}
}
);
// 以下是asm操作字节码
ClassEmitter e = new ClassEmitter(v);
// useFactory => true
// net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$a7ee9d2a
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 );
// [<init>()V]
List constructorInfo = CollectionUtils.transform(constructors, MethodInfoTransformer.getInstance());
e.declare_field(Constants.ACC_PRIVATE, BOUND_FIELD, Type.BOOLEAN_TYPE, null);
// interceptDuringConstruction => true
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);
}
emitMethods(e, methods, actualMethods);
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();
}
主要 是获取代理类的所有方法 和 代理类所实现接口的所有方法 用字节码将 所有的方法写到一个代理的类中,
具体生成的class文件反编译之后如下:
Bean$$EnhancerByCGLIB$$f51d20a3
package net.sf.cglib.samples;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Method;
import org.apache.tools.ant.taskdefs.Get;
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 Bean$$EnhancerByCGLIB$$f51d20a3 extends Bean 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 static final Method CGLIB$toString$0$Method;
private static final MethodProxy CGLIB$toString$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$setSampleProperty$1$Method;
private static final MethodProxy CGLIB$setSampleProperty$1$Proxy;
private static final Method CGLIB$getSampleProperty$2$Method;
private static final MethodProxy CGLIB$getSampleProperty$2$Proxy;
private static final Method CGLIB$addPropertyChangeListener$3$Method;
private static final MethodProxy CGLIB$addPropertyChangeListener$3$Proxy;
private static final Method CGLIB$removePropertyChangeListener$4$Method;
private static final MethodProxy CGLIB$removePropertyChangeListener$4$Proxy;
private static final Method CGLIB$finalize$5$Method;
private static final MethodProxy CGLIB$finalize$5$Proxy;
private static final Method CGLIB$equals$6$Method;
private static final MethodProxy CGLIB$equals$6$Proxy;
private static final Method CGLIB$hashCode$7$Method;
private static final MethodProxy CGLIB$hashCode$7$Proxy;
private static final Method CGLIB$clone$8$Method;
private static final MethodProxy CGLIB$clone$8$Proxy;
static {
// CGLIB$STATICHOOK1();
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class localClass1 = null;
try {
localClass1 = Class.forName("net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Class localClass2 = null;
Method[] tmp83_80 = null;
try {
tmp83_80 = ReflectUtils.findMethods(new String[] { "finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (localClass2 = Class.forName("java.lang.Object")).getDeclaredMethods());
} catch (SecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
CGLIB$finalize$5$Method = tmp83_80[0];
CGLIB$finalize$5$Proxy = MethodProxy.create(localClass2, localClass1, "()V", "finalize", "CGLIB$finalize$5");
Method[] tmp103_83 = tmp83_80;
CGLIB$equals$6$Method = tmp103_83[1];
CGLIB$equals$6$Proxy = MethodProxy.create(localClass2, localClass1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$6");
Method[] tmp123_103 = tmp103_83;
CGLIB$hashCode$7$Method = tmp123_103[2];
CGLIB$hashCode$7$Proxy = MethodProxy.create(localClass2, localClass1, "()I", "hashCode", "CGLIB$hashCode$7");
Method[] tmp143_123 = tmp123_103;
CGLIB$clone$8$Method = tmp143_123[3];
CGLIB$clone$8$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$8");
try {
localClass2 = Class.forName("net.sf.cglib.samples.Bean");
} catch (ClassNotFoundException e) {
}
// tmp143_123;
Method[] tmp236_233 = ReflectUtils.findMethods(new String[] {
"toString",
"()Ljava/lang/String;",
"setSampleProperty",
"(Ljava/lang/String;)V",
"getSampleProperty",
"()Ljava/lang/String;",
"addPropertyChangeListener",
"(Ljava/beans/PropertyChangeListener;)V",
"removePropertyChangeListener",
"(Ljava/beans/PropertyChangeListener;)V"
},
localClass2.getDeclaredMethods()
);
CGLIB$toString$0$Method = tmp236_233[0];
CGLIB$toString$0$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/String;", "toString", "CGLIB$toString$0");
Method[] tmp256_236 = tmp236_233;
CGLIB$setSampleProperty$1$Method = tmp256_236[1];
CGLIB$setSampleProperty$1$Proxy = MethodProxy.create(localClass2, localClass1, "(Ljava/lang/String;)V", "setSampleProperty", "CGLIB$setSampleProperty$1");
Method[] tmp276_256 = tmp256_236;
CGLIB$getSampleProperty$2$Method = tmp276_256[2];
CGLIB$getSampleProperty$2$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/String;", "getSampleProperty", "CGLIB$getSampleProperty$2");
Method[] tmp296_276 = tmp276_256;
CGLIB$addPropertyChangeListener$3$Method = tmp296_276[3];
CGLIB$addPropertyChangeListener$3$Proxy = MethodProxy.create(localClass2, localClass1, "(Ljava/beans/PropertyChangeListener;)V", "addPropertyChangeListener", "CGLIB$addPropertyChangeListener$3");
Method[] tmp316_296 = tmp296_276;
CGLIB$removePropertyChangeListener$4$Method = tmp316_296[4];
CGLIB$removePropertyChangeListener$4$Proxy = MethodProxy.create(localClass2, localClass1, "(Ljava/beans/PropertyChangeListener;)V", "removePropertyChangeListener", "CGLIB$removePropertyChangeListener$4");
// tmp316_296;
}
static void CGLIB$STATICHOOK1() {
}
final String CGLIB$toString$0() {
return super.toString();
}
public final String toString() {
MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
if (tmp4_1 == null) {
CGLIB$BIND_CALLBACKS(this);
}
MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;
if (tmp17_14 != null) {
try {
return (String)tmp17_14.intercept(this, CGLIB$toString$0$Method, CGLIB$emptyArgs, CGLIB$toString$0$Proxy);
} catch (Throwable e) {
}
}
return super.toString();
}
final void CGLIB$setSampleProperty$1(String paramString) {
super.setSampleProperty(paramString);
}
public final void setSampleProperty(String paramString) {
MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
if (tmp4_1 == null) {
CGLIB$BIND_CALLBACKS(this);
}
if (this.CGLIB$CALLBACK_0 != null) {
try {
tmp4_1.intercept(this, CGLIB$setSampleProperty$1$Method, new Object[] {paramString}, CGLIB$setSampleProperty$1$Proxy);
return;
} catch (Throwable e) {
}
}
super.setSampleProperty(paramString);
}
// CGLIB$emptyArgs
final String CGLIB$getSampleProperty$2() {
return super.getSampleProperty();
}
public final String getSampleProperty() {
MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
if (tmp4_1 == null) {
CGLIB$BIND_CALLBACKS(this);
}
MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;
if (tmp17_14 != null) {
try {
return (String)tmp17_14.intercept(this, CGLIB$getSampleProperty$2$Method, CGLIB$emptyArgs, CGLIB$getSampleProperty$2$Proxy);
} catch (Throwable e) {
e.printStackTrace();
}
}
return super.getSampleProperty();
}
final void CGLIB$addPropertyChangeListener$3(PropertyChangeListener paramPropertyChangeListener) {
// compile error! superClass is abstract
// super.addPropertyChangeListener(paramPropertyChangeListener);
}
public final void addPropertyChangeListener(PropertyChangeListener paramPropertyChangeListener) {
MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
if (tmp4_1 == null) {
// tmp4_1;
CGLIB$BIND_CALLBACKS(this);
}
if (this.CGLIB$CALLBACK_0 != null) {
try {
tmp4_1.intercept(this, CGLIB$addPropertyChangeListener$3$Method, new Object[]{paramPropertyChangeListener}, CGLIB$addPropertyChangeListener$3$Proxy);
return;
} catch (Throwable e) {
}
}
// compile error! superClass is abstract
// super.addPropertyChangeListener(paramPropertyChangeListener);
}
final void CGLIB$removePropertyChangeListener$4(PropertyChangeListener paramPropertyChangeListener) {
// compile error! superClass is abstract
// super.removePropertyChangeListener(paramPropertyChangeListener);
}
public final void removePropertyChangeListener(PropertyChangeListener paramPropertyChangeListener) {
MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
if (tmp4_1 == null) {
// tmp4_1;
CGLIB$BIND_CALLBACKS(this);
}
if (this.CGLIB$CALLBACK_0 != null) {
try {
tmp4_1.intercept(this, CGLIB$removePropertyChangeListener$4$Method, new Object[]{paramPropertyChangeListener}, CGLIB$removePropertyChangeListener$4$Proxy);
return;
} catch (Throwable e) {
}
}
// super.removePropertyChangeListener(paramPropertyChangeListener);
}
final void CGLIB$finalize$5() throws Throwable {
super.finalize();
}
protected final void finalize() throws Throwable {
MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
if (tmp4_1 == null) {
CGLIB$BIND_CALLBACKS(this);
}
if (this.CGLIB$CALLBACK_0 != null) {
tmp4_1.intercept(this, CGLIB$finalize$5$Method, CGLIB$emptyArgs, CGLIB$finalize$5$Proxy);
return;
}
super.finalize();
}
final boolean CGLIB$equals$6(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;
try {
tmp41_36 = tmp17_14.intercept(this, CGLIB$equals$6$Method, new Object[] { paramObject }, CGLIB$equals$6$Proxy);
return tmp41_36 == null ? false : ((Boolean)tmp41_36).booleanValue();
} catch (Throwable e) {
e.printStackTrace();
}
}
return super.equals(paramObject);
}
final int CGLIB$hashCode$7() {
return super.hashCode();
}
public final int hashCode() {
MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
if (tmp4_1 == null) {
CGLIB$BIND_CALLBACKS(this);
}
MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;
if (tmp17_14 != null) {
Object tmp36_31;
try {
tmp36_31 = tmp17_14.intercept(this, CGLIB$hashCode$7$Method, CGLIB$emptyArgs, CGLIB$hashCode$7$Proxy);
return tmp36_31 == null ? 0 : ((Number)tmp36_31).intValue();
} catch (Throwable e) {
}
}
return super.hashCode();
}
final Object CGLIB$clone$8() throws CloneNotSupportedException {
return super.clone();
}
protected final Object clone() throws CloneNotSupportedException {
MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
if (tmp4_1 == null) {
CGLIB$BIND_CALLBACKS(this);
}
MethodInterceptor tmp17_14 = this.CGLIB$CALLBACK_0;
if (tmp17_14 != null) {
try {
return tmp17_14.intercept(this, CGLIB$clone$8$Method, CGLIB$emptyArgs, CGLIB$clone$8$Proxy);
} catch (Throwable e) {
// e.printStackTrace();
return null;
}
}
return super.clone();
}
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$5$Proxy;
break;
case -1148146316:
if(tmp4_1.equals("addPropertyChangeListener(Ljava/beans/PropertyChangeListener;)V"))
return CGLIB$addPropertyChangeListener$3$Proxy;
case -727109664:
if(tmp4_1.equals("getSampleProperty()Ljava/lang/String;"))
return CGLIB$getSampleProperty$2$Proxy;
case -508378822:
if(tmp4_1.equals("clone()Ljava/lang/Object;"))
return CGLIB$clone$8$Proxy;
case -182669826:
if(tmp4_1.equals("setSampleProperty(Ljava/lang/String;)V"))
return CGLIB$setSampleProperty$1$Proxy;
case -112787753:
if(tmp4_1.equals("removePropertyChangeListener(Ljava/beans/PropertyChangeListener;)V"))
return CGLIB$removePropertyChangeListener$4$Proxy;
case 1826985398:
if(tmp4_1.equals("equals(Ljava/lang/Object;)Z"))
return CGLIB$equals$6$Proxy;
case 1913648695:
if(tmp4_1.equals("toString()Ljava/lang/String;"))
return CGLIB$toString$0$Proxy;
case 1984935277:
if(tmp4_1.equals("hashCode()I"))
return CGLIB$hashCode$7$Proxy;
default:
return CGLIB$finalize$5$Proxy;
}
return null;
}
public Bean$$EnhancerByCGLIB$$f51d20a3() {
CGLIB$BIND_CALLBACKS(this);
}
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) {
if(paramObject instanceof Bean$$EnhancerByCGLIB$$f51d20a3) {
Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = (Bean$$EnhancerByCGLIB$$f51d20a3)paramObject;
if(f51d20a3.CGLIB$BOUND) {
return;
}
f51d20a3.CGLIB$BOUND = true;
Object obj = CGLIB$THREAD_CALLBACKS.get();
if(obj != null) {
Callback[] callbacks = (Callback[])obj;
MethodInterceptor interceptor = (MethodInterceptor)callbacks[0];
f51d20a3.CGLIB$CALLBACK_0 = interceptor;
return;
}
if(CGLIB$STATIC_CALLBACKS != null)
f51d20a3.CGLIB$CALLBACK_0 = (MethodInterceptor)CGLIB$STATIC_CALLBACKS[0];
}
}
public Object newInstance(Callback[] paramArrayOfCallback) {
CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback);
Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = new Bean$$EnhancerByCGLIB$$f51d20a3();
CGLIB$SET_THREAD_CALLBACKS(null);
return f51d20a3;
}
public Object newInstance(Callback paramCallback) {
CGLIB$SET_THREAD_CALLBACKS(new Callback[] { paramCallback });
Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = new Bean$$EnhancerByCGLIB$$f51d20a3();
CGLIB$SET_THREAD_CALLBACKS(null);
return f51d20a3;
}
public Object newInstance(Class[] paramArrayOfClass, Object[] paramArrayOfObject, Callback[] paramArrayOfCallback) {
CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback);
Class[] tmp9_8 = paramArrayOfClass;
Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = null;
switch (tmp9_8.length) {
case 0:
f51d20a3 = new Bean$$EnhancerByCGLIB$$f51d20a3();
break;
default:
throw new IllegalArgumentException("Constructor not found");
}
CGLIB$SET_THREAD_CALLBACKS(null);
return f51d20a3;
}
public Callback getCallback(int paramInt) {
CGLIB$BIND_CALLBACKS(this);
switch (paramInt) {
case 0:
break;
}
return null;
}
public void setCallback(int paramInt, Callback paramCallback) {
switch (paramInt) {
case 0:
this.CGLIB$CALLBACK_0 = ((MethodInterceptor) paramCallback);
break;
}
}
public Callback[] getCallbacks() {
CGLIB$BIND_CALLBACKS(this);
return new Callback[] { this.CGLIB$CALLBACK_0 };
}
public void setCallbacks(Callback[] paramArrayOfCallback) {
this.CGLIB$CALLBACK_0 = ((MethodInterceptor) paramArrayOfCallback[0]);
}
}
再回到 AbstractClassGenerator 类中 的create 方法中 ,最后有个 firstInstance方法的调用
protected Object firstInstance(Class type) throws Exception {
if (classOnly) {
return type;
} else {
return createUsingReflection(type);
}
}
看 createUsingReflection 方法
private Object createUsingReflection(Class type) {
setThreadCallbacks(type, callbacks);
try {
if (argumentTypes != null) {
return ReflectUtils.newInstance(type, argumentTypes, arguments);
} else {
return ReflectUtils.newInstance(type);
}
} finally {
// clear thread callbacks to allow them to be gc'd
setThreadCallbacks(type, null);
}
}
再看
setThreadCallbacks(type, callbacks);
private static void setThreadCallbacks(Class type, Callback[] callbacks) {
setCallbacksHelper(type, callbacks, SET_THREAD_CALLBACKS_NAME);// CGLIB$SET_THREAD_CALLBACKS
}
private static void setCallbacksHelper(Class type, Callback[] callbacks, String methodName) {
// TODO: optimize
try {
Method setter = getCallbacksSetter(type, methodName);
setter.invoke(null, new Object[] { callbacks });
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException(type + " is not an enhanced class");
} catch (IllegalAccessException e) {
throw new CodeGenerationException(e);
} catch (InvocationTargetException e) {
throw new CodeGenerationException(e);
}
}
主要是反射 Bean$$EnhancerByCGLIB$$f51d20a3 类 中 的静态CGLIB$SET_THREAD_CALLBACKS方法
public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback) {
CGLIB$THREAD_CALLBACKS.set(paramArrayOfCallback);
}
将 MethodInterceptor 接口的实现类 注入到ThreadLocal 中, 主要作用是 代理类在 进行实际调用方法之前先调用
MethodInterceptor 接口的intercept方法, 本例子中就是 Beans 类,
public class Beans implements MethodInterceptor
接下来 是通过反射设立一个 Bean$$EnhancerByCGLIB$$f51d20a3 对象, 查看 Bean$$EnhancerByCGLIB$$f51d20a3 类的构造方法
public Bean$$EnhancerByCGLIB$$f51d20a3() {
CGLIB$BIND_CALLBACKS(this);
}
private static final void CGLIB$BIND_CALLBACKS(Object paramObject) {
if(paramObject instanceof Bean$$EnhancerByCGLIB$$f51d20a3) {
Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = (Bean$$EnhancerByCGLIB$$f51d20a3)paramObject;
if(f51d20a3.CGLIB$BOUND) {
return;
}
f51d20a3.CGLIB$BOUND = true;
Object obj = CGLIB$THREAD_CALLBACKS.get();
if(obj != null) {
Callback[] callbacks = (Callback[])obj;
MethodInterceptor interceptor = (MethodInterceptor)callbacks[0];
f51d20a3.CGLIB$CALLBACK_0 = interceptor;
return;
}
if(CGLIB$STATIC_CALLBACKS != null)
f51d20a3.CGLIB$CALLBACK_0 = (MethodInterceptor)CGLIB$STATIC_CALLBACKS[0];
}
}
以上代码主要是为代理类Bean$$EnhancerByCGLIB$$f51d20a3类中的 属性 private MethodInterceptor CGLIB$CALLBACK_0; 进行赋值,也就是 为代理类注册 拦截器(
MethodInterceptor )的方法
此时 Bean$$EnhancerByCGLIB$$f51d20a3 实例化完成
再回到例子代码中 bean.setSampleProperty("TEST"); 调用代理类的 setSampleProperty
Bean$$EnhancerByCGLIB$$f51d20a3类的 setSampleProperty方法如下:
public final void setSampleProperty(String paramString) {
MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
if (tmp4_1 == null) {
CGLIB$BIND_CALLBACKS(this);
}
if (this.CGLIB$CALLBACK_0 != null) {
try {
tmp4_1.intercept(this, CGLIB$setSampleProperty$1$Method, new Object[] {paramString}, CGLIB$setSampleProperty$1$Proxy);
return;
} catch (Throwable e) {
}
}
super.setSampleProperty(paramString);
}
以上代码先 回调 拦截器(MethodInterceptor)
intercept 方法, 此时 代码转回 Beans类的 intercept 方法
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
Object retValFromSuper = null;
try {
if (!Modifier.isAbstract(method.getModifiers())) {
retValFromSuper = proxy.invokeSuper(obj, args);
}
} finally {
String name = method.getName();
if( name.equals("addPropertyChangeListener")) {
addPropertyChangeListener((PropertyChangeListener)args[0]);
} else if ( name.equals( "removePropertyChangeListener" ) ){
removePropertyChangeListener((PropertyChangeListener)args[0]);
}
if( name.startsWith("set") && args.length == 1 && method.getReturnType() == Void.TYPE ){
char propName[] = name.substring("set".length()).toCharArray();
propName[0] = Character.toLowerCase( propName[0] );
propertySupport.firePropertyChange( new String( propName ) , null , args[0]);
}
}
return retValFromSuper;
}
intercept方法的第4个参数的来源于代理类 Bean$$EnhancerByCGLIB$$f51d20a3 类的初始化静态方法 static {}
CGLIB$getSampleProperty$2$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/String;", "getSampleProperty", "CGLIB$getSampleProperty$2");
接下来转到 retValFromSuper = proxy.invokeSuper(obj, args);
MethodProxy类
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
再看 init(); 方法
private void init() {
if (fastClassInfo == null) {
synchronized (initLock) {
if (fastClassInfo == null) {
CreateInfo ci = createInfo;
FastClassInfo fci = new FastClassInfo();
fci.f1 = helper(ci, ci.c1);// class net.sf.cglib.samples.Bean
fci.f2 = helper(ci, ci.c2);// class net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3
fci.i1 = fci.f1.getIndex(sig1);// setSampleProperty(Ljava/lang/String;)V class net.sf.cglib.samples.Bean
fci.i2 = fci.f2.getIndex(sig2);// CGLIB$setSampleProperty$1(Ljava/lang/String;)V class net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3
fastClassInfo = fci;
createInfo = null;
}
}
}
}
fci.f1 = helper(ci, ci.c1);// class net.sf.cglib.samples.Bean
private static FastClass helper(CreateInfo ci, Class type) {
FastClass.Generator g = new FastClass.Generator();
g.setType(type);// class net.sf.cglib.samples.Bean class net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$23fe786a
g.setClassLoader(ci.c2.getClassLoader());
g.setNamingPolicy(ci.namingPolicy);
g.setStrategy(ci.strategy);
g.setAttemptLoad(ci.attemptLoad);
return g.create();
}
最终会转到 FastClass类的 generateClass方法
public void generateClass(ClassVisitor v) throws Exception {
new FastClassEmitter(v, getClassName(), type);
}
fci.f2 = helper(ci, ci.c2);// class net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3
以上2行代码 会动态的 创建2个继承 FastClass 的类
一个是 Bean$$FastClassByCGLIB$$f4d01dac 主要是包装 net.sf.cglib.samples.Bean 类
另一个Bean$$EnhancerByCGLIB$$f51d20a3$$FastClassByCGLIB$$e12a516c 主要是包装 net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3(代理类)
具体反编译的代码如下
Bean$$FastClassByCGLIB$$f4d01dac
package net.sf.cglib.samples;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import net.sf.cglib.core.Signature;
import net.sf.cglib.reflect.FastClass;
public class Bean$$FastClassByCGLIB$$f4d01dac extends FastClass {
public Bean$$FastClassByCGLIB$$f4d01dac(Class paramClass) {
super(paramClass);
}
public int getIndex(Signature paramSignature) {
String tmp4_1 = paramSignature.toString();
switch (tmp4_1.hashCode()) {
case -1725733088:
if (tmp4_1.equals("getClass()Ljava/lang/Class;"))
return 10;
break;
case -1148146316:
if(tmp4_1.equals("addPropertyChangeListener(Ljava/beans/PropertyChangeListener;)V"))
return 3;
case -1026001249:
if(tmp4_1.equals("wait(JI)V"))
return 6;
case -727109664:
if(tmp4_1.equals("getSampleProperty()Ljava/lang/String;"))
return 2;
case -182669826:
case -112787753:
case 243996900:
case 946854621:
case 1116248544:
case 1826985398:
case 1902039948:
case 1913648695:
case 1984935277:
}
return -1;
}
public int getIndex(String paramString, Class[] paramArrayOfClass) {
String tmp3_0 = paramString;
switch (tmp3_0.hashCode()) {
case -2043397483:
if (tmp3_0.equals("getSampleProperty")) {
Class[] tmp112_1 = paramArrayOfClass;
switch (tmp112_1.length) {
case 0:
return 2;
default:
}
}
break;
case -1776922004:
case -1645115555:
case -1295482945:
case -1117363270:
case -1039689911:
case 3641717:
case 147696667:
case 1311416993:
case 1902066072:
case 1950568386:
}
return -1;
}
public int getIndex(Class[] paramArrayOfClass) {
Class[] tmp1_0 = paramArrayOfClass;
switch (tmp1_0.length) {
case 0:
return 0;
default:
}
return -1;
}
public Object invoke(int paramInt, Object paramObject, Object[] paramArrayOfObject) throws InvocationTargetException {
try {
Bean bean = (Bean)paramObject;
switch(paramInt) {
case 0:
return bean.toString();
case 1:
bean.setSampleProperty((String)paramArrayOfObject[0]);
return null;
case 2:
return bean.getSampleProperty();
case 3:
bean.addPropertyChangeListener((PropertyChangeListener)paramArrayOfObject[0]);
return null;
case 4:
bean.removePropertyChangeListener((PropertyChangeListener)paramArrayOfObject[0]);
return null;
case 5:
bean.wait();
return null;
case 6:
bean.wait(((Number)paramArrayOfObject[0]).longValue(), (int)paramArrayOfObject[1]);
return null;
case 7:
bean.wait(((Number)paramArrayOfObject[0]).longValue());
return null;
case 8:
return bean.equals(paramArrayOfObject[0]);
case 9:
return bean.hashCode();
case 10:
return bean.getClass();
case 11:
bean.notify();
return null;
case 12:
bean.notifyAll();
return null;
default:
}
} catch(Throwable ex) {
throw new InvocationTargetException(ex);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public Object newInstance(int paramInt, Object[] paramArrayOfObject) throws InvocationTargetException {
try {
switch (paramInt) {
case 0:
return new Bean() {
public void removePropertyChangeListener(PropertyChangeListener listener) {
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
}
};
default:
}
} catch (Throwable localThrowable) {
throw new InvocationTargetException(localThrowable);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public int getMaxIndex() {
return 12;
}
}
Bean$$EnhancerByCGLIB$$f51d20a3$$FastClassByCGLIB$$e12a516c 类
package net.sf.cglib.samples;
import java.lang.reflect.InvocationTargetException;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.reflect.FastClass;
public class Bean$$EnhancerByCGLIB$$f51d20a3$$FastClassByCGLIB$$e12a516c extends FastClass {
public Bean$$EnhancerByCGLIB$$f51d20a3$$FastClassByCGLIB$$e12a516c(Class paramClass) {
super(paramClass);
}
public int getIndex(Signature paramSignature) {
String tmp4_1 = paramSignature.toString();
switch (tmp4_1.hashCode()) {
case -2055565910:
if (tmp4_1.equals("CGLIB$SET_THREAD_CALLBACKS([Lnet/sf/cglib/proxy/Callback;)V"))
return 17;
break;
case -1725733088:
if(tmp4_1.equals("getClass()Ljava/lang/Class;")) {
return 32;
}
break;
case -1682551285:
if(tmp4_1.equals("CGLIB$getSampleProperty$2()Ljava/lang/String;")) {
return 20;
}
break;
case -1649069589:
if(tmp4_1.equals("CGLIB$clone$8()Ljava/lang/Object;")) {
return 26;
}
break;
case -1574182249:
case -1457535688:
case -1411723561:
case -1184739478:
case -1148146316:
case -1026001249:
case -894172689:
case -727109664:
case -623122092:
case -508378822:
case -419626537:
case -182669826:
case -112787753:
case 243996900:
case 246779284:
case 560567118:
case 687209440:
case 811063227:
case 812055105:
case 883767110:
case 946854621:
case 973717575:
case 1116248544:
case 1221173700:
case 1230699260:
case 1365196803:
case 1584330438:
case 1826985398:
case 1902039948:
case 1913648695:
case 1984935277:
}
return 2;
}
public int getIndex(String paramString, Class[] paramArrayOfClass) {
String tmp3_0 = paramString;
switch (tmp3_0.hashCode()) {
case -2083498446:
if (tmp3_0.equals("CGLIB$finalize$5")) {
Class[] tmp272_1 = paramArrayOfClass;
switch (tmp272_1.length) {
case 0:
return 23;
default:
}
}
break;
case -2043397483:
if(tmp3_0.equals("getSampleProperty")) {
Class[] tmp272_1 = paramArrayOfClass;
switch (tmp272_1.length) {
case 0:
return 13;
default:
}
}
case -1776922004:
case -1668635866:
case -1645115555:
case -1295482945:
case -1117363270:
case -1053468136:
case -1039689911:
case -681255906:
case -277508560:
case -124978604:
case -60403779:
case -29025551:
case 3641717:
case 85179481:
case 94756189:
case 147696667:
case 161998109:
case 495524492:
case 539783499:
case 1154623345:
case 1311416993:
case 1543336187:
case 1811874389:
case 1817099975:
case 1902066072:
case 1905679803:
case 1950568386:
case 1951977614:
case 2083511360:
}
return 2;
}
public int getIndex(Class[] paramArrayOfClass) {
Class[] tmp1_0 = paramArrayOfClass;
switch (tmp1_0.length) {
case 0:
return 0;
default:
}
return 2;
}
public Object invoke(int paramInt, Object paramObject, Object[] paramArrayOfObject) throws InvocationTargetException {
try {
if(paramObject instanceof net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3) {
Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = (Bean$$EnhancerByCGLIB$$f51d20a3)paramObject;
switch(paramInt) {
case 0:
f51d20a3.CGLIB$finalize$5();
return null;
case 1:
return f51d20a3.CGLIB$equals$6(paramArrayOfObject[0]);
case 2:
return f51d20a3.CGLIB$toString$0();
case 3:
return f51d20a3.CGLIB$hashCode$7();
case 4:
return f51d20a3.CGLIB$clone$8();
case 5:
return f51d20a3.newInstance((java.lang.Class[])paramArrayOfObject[0], (java.lang.Object[])paramArrayOfObject[1], (net.sf.cglib.proxy.Callback[])paramArrayOfObject[2]);
case 6:
return f51d20a3.newInstance((net.sf.cglib.proxy.Callback)paramArrayOfObject[0]);
case 7:
return f51d20a3.newInstance((net.sf.cglib.proxy.Callback[])paramArrayOfObject[0]);
case 8:
f51d20a3.setCallback(((Number)paramArrayOfObject[0]).intValue(), (Callback)paramArrayOfObject[1]);
return null;
case 9:
return f51d20a3.getCallback(((Number)paramArrayOfObject[0]).intValue());
case 10:
f51d20a3.setCallbacks((Callback[])paramArrayOfObject[0]);
return null;
// 下面省略N个方法
}
}
} catch(Throwable ex) {
throw new InvocationTargetException(ex);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public Object newInstance(int paramInt, Object[] paramArrayOfObject) throws InvocationTargetException {
try {
switch (paramInt) {
case 0:
return new Bean$$EnhancerByCGLIB$$f51d20a3();
}
} catch (Throwable localThrowable) {
throw new InvocationTargetException(localThrowable);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
public int getMaxIndex() {
return 34;
}
}
之后再转到 MethodProxy类中的 invokeSuper 方法中
public Object invokeSuper(Object obj, Object[] args) throws Throwable {
try {
init();
FastClassInfo fci = fastClassInfo;
return fci.f2.invoke(fci.i2, obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
return fci.f2.invoke(fci.i2, obj, args);
再看 Bean$$EnhancerByCGLIB$$f51d20a3$$FastClassByCGLIB$$e12a516c 类的invoke方法
public Object invoke(int paramInt, Object paramObject, Object[] paramArrayOfObject) throws InvocationTargetException {
try {
if(paramObject instanceof net.sf.cglib.samples.Bean$$EnhancerByCGLIB$$f51d20a3) {
Bean$$EnhancerByCGLIB$$f51d20a3 f51d20a3 = (Bean$$EnhancerByCGLIB$$f51d20a3)paramObject;
switch(paramInt) {
case 0:
f51d20a3.CGLIB$finalize$5();
return null;
case 1:
return f51d20a3.CGLIB$equals$6(paramArrayOfObject[0]);
case 2:
return f51d20a3.CGLIB$toString$0();
case 3:
return f51d20a3.CGLIB$hashCode$7();
case 4:
return f51d20a3.CGLIB$clone$8();
case 5:
return f51d20a3.newInstance((java.lang.Class[])paramArrayOfObject[0], (java.lang.Object[])paramArrayOfObject[1], (net.sf.cglib.proxy.Callback[])paramArrayOfObject[2]);
case 6:
return f51d20a3.newInstance((net.sf.cglib.proxy.Callback)paramArrayOfObject[0]);
case 7:
return f51d20a3.newInstance((net.sf.cglib.proxy.Callback[])paramArrayOfObject[0]);
case 8:
f51d20a3.setCallback(((Number)paramArrayOfObject[0]).intValue(), (Callback)paramArrayOfObject[1]);
return null;
case 9:
return f51d20a3.getCallback(((Number)paramArrayOfObject[0]).intValue());
case 10:
f51d20a3.setCallbacks((Callback[])paramArrayOfObject[0]);
return null;
// 下面省略N个方法
}
}
} catch(Throwable ex) {
throw new InvocationTargetException(ex);
}
throw new IllegalArgumentException("Cannot find matching method/constructor");
}
在以上的方法中会调到 代理类 Bean$$EnhancerByCGLIB$$f51d20a3 的 CGLIB$setSampleProperty$1 方法
final void CGLIB$setSampleProperty$1(String paramString) {
super.setSampleProperty(paramString);
}
因为 Bean$$EnhancerByCGLIB$$f51d20a3 代理类继承 Bean 类 所以 super.setSampleProperty(paramString); 在调用 Bean 类中的 setSampleProperty方法
到此为止整个代理的过程就结束了.
总结
cglib和JDK 的动态代理区别
cglib 既可以代理类,也可以代理接口, cglib 在代理类时 要继承 目标的类 ,
jdk的动态代理只能代理接口. 只能实现目标的接口
通俗一点说原理吧,
JDK 只能代理接口是因为 它只反射出接口中的所有方法, 然后将所有的方法写到一个新的class文件中,既代理的类,再用native的类的加载器进行加载。
而cglib 代理类, 是反射本类中的所有方法和接口中的所有方法 , 再用类加载加载Class 文件,
cglib 类加载器获取的方式是通过反射
private static Method DEFINE_CLASS;
private static final ProtectionDomain PROTECTION_DOMAIN;
static {
PROTECTION_DOMAIN = getProtectionDomain(ReflectUtils.class);
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
try {
Class loader = Class.forName("java.lang.ClassLoader"); // JVM crash w/o this
DEFINE_CLASS = loader.getDeclaredMethod(
"defineClass",
new Class[] {
String.class,
byte[].class,
Integer.TYPE,
Integer.TYPE,
ProtectionDomain.class
}
);
DEFINE_CLASS.setAccessible(true);
} catch (ClassNotFoundException e) {
throw new CodeGenerationException(e);
} catch (NoSuchMethodException e) {
throw new CodeGenerationException(e);
}
return null;
}
});
}
public static ProtectionDomain getProtectionDomain(final Class source) {
if(source == null) {
return null;
}
return (ProtectionDomain)AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
return source.getProtectionDomain();
}
});
}
=======
之前写了一次很详细的过程, 不知怎么回事没保存就闪退了,没保存上, 又写了第二遍, 没有之前的那次写的详细了,/(ㄒoㄒ)/~~.
最后附上完成的工程,有想看的朋友可以下载, 以上有些代码无法反编译,是我自己读asm文件翻转成Java代码的,不一定会100%的准确, 但大致的思路是对的, 如有错误也请大家纠正,谢谢.
- 大小: 251.6 KB
- 大小: 104.8 KB
- 大小: 119.4 KB
分享到:
相关推荐
JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源...
JavaEE源代码 cglib-2.2_beta1JavaEE源代码 cglib-2.2_beta1JavaEE源代码 cglib-2.2_beta1JavaEE源代码 cglib-2.2_beta1JavaEE源代码 cglib-2.2_beta1JavaEE源代码 cglib-2.2_beta1JavaEE源代码 cglib-2.2_beta1...
- `cglib-src-2.2.3.jar`:包含了CGLIB的源代码,可以通过阅读源代码深入理解其工作原理。 - `cglib-docs-2.2.3.jar`:提供了CGLIB的API文档,有助于快速查找和理解类库中的方法和类。 - `cglib-nodep-2.2.3.jar`:...
CGlib(Code Generation Library)是一个强大的、高性能的代码生成库,它在运行期扩展Java类与实现Java接口。当目标类没有实现接口时,CGlib就派上用场了。CGlib通过创建目标类的子类并在子类中织入增强逻辑来实现...
Java CGLib 实例代码 Java CGLib 实例代码是 Java 中强大的三个特征:反射、Proxy 和元数据的结合,使得 Java 能够实现强悍的框架。CGLib(Code Generation Library)和 ASM 使得 Java 能够生成强悍的框架,虽然...
《Spring源代码分析:AOP的实现》 在软件开发领域,Spring框架因其强大的功能和易用性,已经成为Java企业级应用的事实标准。其中,面向切面编程(Aspect Oriented Programming,简称AOP)是Spring的重要特性之一,...
《Hibernate 3.2.5源代码分析》 Hibernate,作为一个强大的对象关系映射(ORM)框架,一直以来都是Java开发中的重要工具。源代码分析对于理解其内部工作原理、优化性能以及解决实际问题至关重要。本篇文章将深入...
CGLIB是基于ASM(一个底层的Java字节码操作和分析框架)来实现的,它允许开发者在运行时为Java类创建子类,而无需访问其源代码或重新编译。这种技术在许多场景下都非常有用,比如实现AOP(面向切面编程)中的动态...
赠送源代码:cglib-3.1-sources.jar; 赠送Maven依赖信息文件:cglib-3.1.pom; 包含翻译后的API文档:cglib-3.1-javadoc-API文档-中文(简体)版.zip; Maven坐标:cglib:cglib:3.1; 标签:cglib、中文文档、jar包、...
CGlib(Code Generation Library)是一个强大的高性能的代码生成库,它在运行期扩展Java类与实现Java接口。当目标类不支持代理接口时,可以使用CGlib进行代理。CGlib通过创建目标类的子类并重写其中的方法来实现代理...
它允许开发者在运行时创建和扩展Java类,而无需直接编写新的源代码或编译步骤。这个压缩包“cglib.zip”很可能包含了CGLib库的源码、文档和其他相关资源。 CGLib的核心功能是通过字节码技术来生成新类。它的工作...
Cglib基于ASM库,能够在字节码层面操作Java类,通过生成子类来实现对目标类的扩展,而无需修改源代码。这种方法尤其适用于那些不支持接口或无法修改源代码的类。 2. **动态代理**:动态代理是Java中一个重要的概念...
它允许开发者在运行时创建和增强新的类或对象,而无需编写任何Java源代码。CGLib是许多流行框架如Spring AOP和Hibernate的重要组成部分。 CGLib3.2.5是该库的一个版本,包含了两个JAR文件:`cglib-3.2.5.jar`和`...
CGlib的核心是ASM库,ASM是一个底层的Java字节码操纵和分析框架,可以用来动态生成类或增强已有类的功能。CGlib在其之上进行了封装,使其更易于使用。下面我们将详细探讨CGlib的主要功能和使用方法: 1. **动态代理...
CGLib,全称为Code Generation Library,是一个强大的高性能的代码生成库,它在Java世界中被广泛应用,尤其是在动态代理和AOP(面向切面编程)领域。这个库的主要功能是能够在运行时动态创建类或者增强已有类的功能...
【CGLib:强大的Java代码生成库】 CGLib(Code Generation Library)是一个强大的、高性能的代码生成库,它在运行期扩展Java类与实现Java接口。这个库最初是为EJB的透明代理而设计的,但后来发展成为了一个广泛的...
CGLIB是一个功能强大,高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。通常可以使用Java的动态代理创建代理,但当要代理的类没有实现接口或者为了更好的性能,CGLIB是一个好...