package Cglib第三方代理;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class DynamicProxy implements MethodInterceptor {
//真实对象
Object targetObject;
public Object getProxyObject(Object object){
this.targetObject = object;
//增强器,动态代码生成器
Enhancer enhancer = new Enhancer();
//回调方法
enhancer.setCallback(this);
//设置生成类的父类类型
enhancer.setSuperclass(targetObject.getClass());
//动态生成字节码并返回代理对象
return enhancer.create();
}
//拦截方法
@Override
public Object intercept(Object arg0, Method arg1, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("Hello,I am the weaved method before");
Object result = methodProxy.invoke(targetObject,args);
System.out.println("Hello,I am the weaved method after");
return result;
}
}
class RealClass{
public void hah(){
System.out.println("我是真实类要处理的东东,也叫切入点,快来增强我");
}
}
package Cglib第三方代理;
import java.io.FileOutputStream;
import java.io.IOException;
import org.junit.Test;
import net.sf.cglib.core.DebuggingClassWriter;
import sun.misc.ProxyGenerator;
public class TestCglibMain {
// RealClass realObject = (RealClass) new DynamicProxy().getProxyObject(new RealClass());
// @Test
// public void test() throws IOException{
// realObject.hah();
//System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "H:\\Hadoop_eclipse\\eclipse-jee-mars-2-win32-x86_64\\剑指Offer\\反射详解\\bin\\cgliballclass");
// String path = "H:/Hadoop_eclipse/eclipse-jee-mars-2-win32-x86_64/剑指Offer/反射详解/bin/cgliballclass/$proxy1.class";
// byte[] classFile = //new byte[1024];
// ProxyGenerator.generateProxyClass("$Proxy1",
// realObject.getClass().getClasses());
// FileOutputStream out = null;
//
// try {
// out = new FileOutputStream(path);
// out.write(classFile);
// out.flush();
// } catch (Exception e) {
// e.printStackTrace();
// } finally {
// try {
// out.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }
public static void main(String[] args) throws IOException {
RealClass realObject = (RealClass) new DynamicProxy().getProxyObject(new RealClass());
realObject.hah();
//System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "H:\\Hadoop_eclipse\\eclipse-jee-mars-2-win32-x86_64\\剑指Offer\\反射详解\\bin\\cgliballclass");
System.in.read();
}
}
package Cglib第三方代理;
import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
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 RealClass$$EnhancerByCGLIB$$afcc55ac
extends RealClass
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$hah$0$Method;
private static final MethodProxy CGLIB$hah$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;
public RealClass$$EnhancerByCGLIB$$afcc55ac()
{
CGLIB$BIND_CALLBACKS(this);
}
static {}
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();
}
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$2$Method, new Object[] { paramObject }, CGLIB$equals$2$Proxy);
tmp41_36;
return tmp41_36 == null ? false : ((Boolean)tmp41_36).booleanValue();
}
return super.equals(paramObject);
}
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$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy);
}
return super.toString();
}
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$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);
tmp36_31;
return tmp36_31 == null ? 0 : ((Number)tmp36_31).intValue();
}
return super.hashCode();
}
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$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy);
}
return super.clone();
}
/* Error */
public Object newInstance(Class[] arg1, Object[] arg2, Callback[] arg3)
{
// Byte code:
// 0: aload_3
// 1: invokestatic 206 Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$SET_THREAD_CALLBACKS ([Lnet/sf/cglib/proxy/Callback;)V
// 4: new 2 Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac
// 7: dup
// 8: aload_1
// 9: dup
// 10: arraylength
// 11: tableswitch default:+24->35, 0:+17->28
// 28: pop
// 29: invokespecial 207 Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:<init> ()V
// 32: goto +17 -> 49
// 35: goto +3 -> 38
// 38: pop
// 39: new 213 java/lang/IllegalArgumentException
// 42: dup
// 43: ldc -41
// 45: invokespecial 218 java/lang/IllegalArgumentException:<init> (Ljava/lang/String;)V
// 48: athrow
// 49: aconst_null
// 50: invokestatic 206 Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$SET_THREAD_CALLBACKS ([Lnet/sf/cglib/proxy/Callback;)V
// 53: areturn
}
public Object newInstance(Callback[] paramArrayOfCallback)
{
CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback);
CGLIB$SET_THREAD_CALLBACKS(null);
return new afcc55ac();
}
public Object newInstance(Callback paramCallback)
{
CGLIB$SET_THREAD_CALLBACKS(new Callback[] { paramCallback });
CGLIB$SET_THREAD_CALLBACKS(null);
return new afcc55ac();
}
public final void hah()
{
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.hah();
}
public void setCallbacks(Callback[] paramArrayOfCallback)
{
this.CGLIB$CALLBACK_0 = ((MethodInterceptor)paramArrayOfCallback[0]);
}
public void setCallback(int paramInt, Callback paramCallback)
{
switch (paramInt)
{
case 0:
this.CGLIB$CALLBACK_0 = ((MethodInterceptor)paramCallback);
break;
}
}
public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] paramArrayOfCallback)
{
CGLIB$STATIC_CALLBACKS = paramArrayOfCallback;
}
public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback)
{
CGLIB$THREAD_CALLBACKS.set(paramArrayOfCallback);
}
public Callback getCallback(int paramInt)
{
CGLIB$BIND_CALLBACKS(this);
switch (paramInt)
{
case 0:
break;
}
return null;
}
public Callback[] getCallbacks()
{
CGLIB$BIND_CALLBACKS(this);
return new Callback[] { this.CGLIB$CALLBACK_0 };
}
final int CGLIB$hashCode$4()
{
return super.hashCode();
}
final void CGLIB$hah$0()
{
super.hah();
}
final String CGLIB$toString$3()
{
return super.toString();
}
final boolean CGLIB$equals$2(Object paramObject)
{
return super.equals(paramObject);
}
final void CGLIB$finalize$1()
throws Throwable
{
super.finalize();
}
final Object CGLIB$clone$5()
throws CloneNotSupportedException
{
return super.clone();
}
private static final void CGLIB$BIND_CALLBACKS(Object paramObject)
{
afcc55ac localafcc55ac = (afcc55ac)paramObject;
if (!localafcc55ac.CGLIB$BOUND)
{
localafcc55ac.CGLIB$BOUND = true;
Object tmp23_20 = CGLIB$THREAD_CALLBACKS.get();
if (tmp23_20 == null)
{
tmp23_20;
CGLIB$STATIC_CALLBACKS;
}
localafcc55ac.CGLIB$CALLBACK_0 = (tmp31_28 == null ? tmp31_28 : (MethodInterceptor)((Callback[])tmp23_20)[0]);
}
}
static void CGLIB$STATICHOOK1()
{
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class localClass1 = Class.forName("Cglib第三方代理.RealClass$$EnhancerByCGLIB$$afcc55ac");
Class localClass2;
Method[] tmp50_47 = ReflectUtils.findMethods(new String[] { "hah", "()V" }, (localClass2 = Class.forName("Cglib第三方代理.RealClass")).getDeclaredMethods());
CGLIB$hah$0$Method = tmp50_47[0];
CGLIB$hah$0$Proxy = MethodProxy.create(localClass2, localClass1, "()V", "hah", "CGLIB$hah$0");
tmp50_47;
Method[] tmp143_140 = ReflectUtils.findMethods(new String[] { "finalize", "()V", "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (localClass2 = Class.forName("java.lang.Object")).getDeclaredMethods());
CGLIB$finalize$1$Method = tmp143_140[0];
CGLIB$finalize$1$Proxy = MethodProxy.create(localClass2, localClass1, "()V", "finalize", "CGLIB$finalize$1");
Method[] tmp163_143 = tmp143_140;
CGLIB$equals$2$Method = tmp163_143[1];
CGLIB$equals$2$Proxy = MethodProxy.create(localClass2, localClass1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");
Method[] tmp183_163 = tmp163_143;
CGLIB$toString$3$Method = tmp183_163[2];
CGLIB$toString$3$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");
Method[] tmp203_183 = tmp183_163;
CGLIB$hashCode$4$Method = tmp203_183[3];
CGLIB$hashCode$4$Proxy = MethodProxy.create(localClass2, localClass1, "()I", "hashCode", "CGLIB$hashCode$4");
Method[] tmp223_203 = tmp203_183;
CGLIB$clone$5$Method = tmp223_203[4];
CGLIB$clone$5$Proxy = MethodProxy.create(localClass2, localClass1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
tmp223_203;
return;
}
/* Error */
public static MethodProxy CGLIB$findMethodProxy(net.sf.cglib.core.Signature arg0)
{
// Byte code:
// 0: aload_0
// 1: invokevirtual 128 java/lang/Object:toString ()Ljava/lang/String;
// 4: dup
// 5: invokevirtual 129 java/lang/Object:hashCode ()I
// 8: lookupswitch default:+132->140, -1574182249:+60->68, -1224815994:+72->80, -508378822:+84->92, 1826985398:+96->104, 1913648695:+108->116, 1984935277:+120->128
// 68: ldc -125
// 70: invokevirtual 132 java/lang/Object:equals (Ljava/lang/Object;)Z
// 73: ifeq +68 -> 141
// 76: getstatic 64 Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$finalize$1$Proxy Lnet/sf/cglib/proxy/MethodProxy;
// 79: areturn
// 80: ldc -122
// 82: invokevirtual 132 java/lang/Object:equals (Ljava/lang/Object;)Z
// 85: ifeq +56 -> 141
// 88: getstatic 46 Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$hah$0$Proxy Lnet/sf/cglib/proxy/MethodProxy;
// 91: areturn
// 92: ldc -120
// 94: invokevirtual 132 java/lang/Object:equals (Ljava/lang/Object;)Z
// 97: ifeq +44 -> 141
// 100: getstatic 125 Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$clone$5$Proxy Lnet/sf/cglib/proxy/MethodProxy;
// 103: areturn
// 104: ldc -118
// 106: invokevirtual 132 java/lang/Object:equals (Ljava/lang/Object;)Z
// 109: ifeq +32 -> 141
// 112: getstatic 77 Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$equals$2$Proxy Lnet/sf/cglib/proxy/MethodProxy;
// 115: areturn
// 116: ldc -116
// 118: invokevirtual 132 java/lang/Object:equals (Ljava/lang/Object;)Z
// 121: ifeq +20 -> 141
// 124: getstatic 94 Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$toString$3$Proxy Lnet/sf/cglib/proxy/MethodProxy;
// 127: areturn
// 128: ldc -114
// 130: invokevirtual 132 java/lang/Object:equals (Ljava/lang/Object;)Z
// 133: ifeq +8 -> 141
// 136: getstatic 107 Cglib第三方代理/RealClass$$EnhancerByCGLIB$$afcc55ac:CGLIB$hashCode$4$Proxy Lnet/sf/cglib/proxy/MethodProxy;
// 139: areturn
// 140: pop
// 141: aconst_null
// 142: areturn
}
}
JDK的代理必须是真实类有接口实现,代理类有InvocationHandler实现,代理类组合真实类有初始化真实类的构造器,
因为Proxy.newInstance需要类加载器,接口class类型,InvocationHandler实现类作为参数传入
Cglib的代理必须是真实类非final,代理类实现MethodInceptor接口,会创建真实类的子类,子类调用某一方法时,先判断
public final void hah()
{
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.hah();
}
可参考https://www.jianshu.com/p/9a61af393e41?from=timeline&isappinstalled=0