jdk和cglib动态代理的区别

原文地址
我只是供自己使用 要理解还是看原文好

//动态代理的测试类
public interface HelloWorld {
	public String sayHello();
}

实现我们的接口

public class HelloWorldImpl implements HelloWorld{

	@Override
	public String sayHello() {
		System.out.println("hello proxy");
		return "你好动态代理";
	}

}

这个是jdk实现动态代理需要实现的类

public class JDKProxyHelloWorld implements InvocationHandler {

	private Object target;

	public Object bind(Object obj){
		target=obj;
		return Proxy.newProxyInstance(
				//得到被代理类的类加载器
				obj.getClass().getClassLoader(),
				//得到被代理类的接口
				obj.getClass().getInterfaces(),
				//代理类
				this);
	}

	@Override//proxy就是代理对象,就是bind方法中返回的对象  method是当前调度的方法也可以说是真实对象的方法  args就是调度方法的参数
	public Object invoke(Object proxy, Method method, Object[] args){
		Object o=null;
		System.out.println("代理之前");
		System.out.println(proxy.getClass().getName());
		try {
			o =method.invoke(target, args);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("代理之后");
		return o;
	}

}

这是main函数 我们可以看出它直接调用bind函数 通过它的接口和类加载器 以及代理类 生成了代理对象
调用代理对象的方法它 代理对象的里面实现了再方法之前执行了我们的方法 它是使用了类似我们的类加载器 再将类化为.class文件的时候 里面添加了我们的invoke方法

public class Main {
	public static void main(String[] args){
		//jdk的动态代理的使用
		HelloWorld proxy=(HelloWorld)new JDKProxyHelloWorld().bind(new HelloWorldImpl());
		//这里使用的是代理对象
		Object o=proxy.sayHello();
		System.out.println(o);
	}
}
public final class $Proxy0 extends Proxy implements UserService {
    //省略部分代码
    private static Method m3;
    public $Proxy0(InvocationHandler h) throws  {
        super(h);
    }
    //代理类的add 方法
    public final void sayHello() throws  {
        try {
            //调用 InvocationHandler 的invoke方法
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
    
            m3 = Class.forName("com.study.spring.proxy.jdk.UserService").getMethod("add", new Class[0]);
            //省略部分代码
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

接下来我们看一看cglib的实现

public class CglibProxy implements MethodInterceptor {

	public Object getProxy(Class clazz){
		Enhancer enhancer=new Enhancer();//增强器
		enhancer.setSuperclass(clazz);//设置超类对象  cglib代理实现的类 是继承了我们传入的类 而不是想jdk的实现了对应类的接口
		enhancer.setCallback(this);//回调函数
		return enhancer.create();
	}

	@Override
	public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
		System.out.println("begin-------"+method.getName()+"----------------------");
		Object result= methodProxy.invokeSuper(o,objects);
		System.out.println("end-------"+method.getName()+"----------------------");
		return result;
	}
}
public class CglibProxyTest {

    public static void main(String[] args){
        //生成代理类到本地
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "com/study/spring/proxy/cglib");
        UserServiceImpl service = new UserServiceImpl();
        CglibProxy cp = new CglibProxy();
        UserService proxy = (UserService) cp.getProxy(service.getClass());
        proxy.add();
    }
}

生成的字节码文件 我们可以明显的看出 它再调用我们的add方法的时候 首先调用了我们设置的callback函数 先将callBack函数中的方法执行了再继续执行 设置的call函数就是我们之前的intercept方法 aop多重应用就只是一层一层的将代理封装了而已

public class UserServiceImpl$$EnhancerByCGLIB$$d166e24d extends UserServiceImpl implements Factory {
    private boolean CGLIB$BOUND;
    public static Object CGLIB$FACTORY_DATA;
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    private static final Callback[] CGLIB$STATIC_CALLBACKS;
    private MethodInterceptor CGLIB$CALLBACK_0;
    private static Object CGLIB$CALLBACK_FILTER;
    private static final Method CGLIB$add$0$Method;
    private static final MethodProxy CGLIB$add$0$Proxy;

    final void CGLIB$add$0() {
        super.add();
    }

    public final void add() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if(this.CGLIB$CALLBACK_0 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if(var10000 != null) {
            var10000.intercept(this, CGLIB$add$0$Method, CGLIB$emptyArgs, CGLIB$add$0$Proxy);
        } else {
            super.add();
        }
    }
    public UserServiceImpl$$EnhancerByCGLIB$$d166e24d() {
        CGLIB$BIND_CALLBACKS(this);
    }

    public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
        CGLIB$THREAD_CALLBACKS.set(var0);
    }

    public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
        CGLIB$STATIC_CALLBACKS = var0;
    }

    private static final void CGLIB$BIND_CALLBACKS(Object var0) {
        UserServiceImpl$$EnhancerByCGLIB$$d166e24d var1 = (UserServiceImpl$$EnhancerByCGLIB$$d166e24d)var0;
        if(!var1.CGLIB$BOUND) {
            var1.CGLIB$BOUND = true;
            Object var10000 = CGLIB$THREAD_CALLBACKS.get();
            if(var10000 == null) {
                var10000 = CGLIB$STATIC_CALLBACKS;
                if(CGLIB$STATIC_CALLBACKS == null) {
                    return;
                }
            }

            var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
        }

    }

    public Object newInstance(Callback[] var1) {
        CGLIB$SET_THREAD_CALLBACKS(var1);
        UserServiceImpl$$EnhancerByCGLIB$$d166e24d var10000 = new UserServiceImpl$$EnhancerByCGLIB$$d166e24d();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Object newInstance(Callback var1) {
        CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
        UserServiceImpl$$EnhancerByCGLIB$$d166e24d var10000 = new UserServiceImpl$$EnhancerByCGLIB$$d166e24d();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
        CGLIB$SET_THREAD_CALLBACKS(var3);
        UserServiceImpl$$EnhancerByCGLIB$$d166e24d var10000 = new UserServiceImpl$$EnhancerByCGLIB$$d166e24d;
        switch(var1.length) {
        case 0:
            var10000.<init>();
            CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
            return var10000;
        default:
            throw new IllegalArgumentException("Constructor not found");
        }
    }

    public Callback getCallback(int var1) {
        CGLIB$BIND_CALLBACKS(this);
        MethodInterceptor var10000;
        switch(var1) {
        case 0:
            var10000 = this.CGLIB$CALLBACK_0;
            break;
        default:
            var10000 = null;
        }

        return var10000;
    }

    public void setCallback(int var1, Callback var2) {
        switch(var1) {
        case 0:
            this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
        default:
        }
    }

    public Callback[] getCallbacks() {
        CGLIB$BIND_CALLBACKS(this);
        return new Callback[]{this.CGLIB$CALLBACK_0};
    }

    public void setCallbacks(Callback[] var1) {
        this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
    }

    static {
        CGLIB$STATICHOOK1();
    }
}
上一篇:ES6学习---Class类与继承


下一篇:java继承注意点