Java中代理分为静态代理和动态代理,其中动态代理又有jdk动态代理和cglib动态代理。

区别如下

类型原理
类的类型生成效率执行效率
jdk动态代理反射机制类必须要实现一个接口较cglib快较cglib慢
cglib动态代理ASM框架,通过FastClass机制直接调用方法可以是普通类较jdk慢
较jdk快

一般的,框架中默认使用jdk动态代理,如果class类没有实现接口的时候,需要转为cglib动态代理。

cglib动态代理例子

这里还是使用之前的例子,张三生病了,来不了公司,委托老王帮他办理请假流程。

下载2个jar包并引入cglib和asm。

https://repo1.maven.org/maven2/cglib/cglib/3.3.0/cglib-3.3.0.jar

https://mvnrepository.com/artifact/org.ow2.asm/asm/9.4

Java中jdk动态代理和cglib动态代理的区别

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * 办理请假,这里需要实现接口。
 */
class BizLeaveImpl implements BizLeave{
    public void doLeave(String name){
        System.out.println(name + "办理请假");
    }
}

interface BizLeave{
    public void doLeave(String name);
}

public class CglibTest{

    public static void main(String[] args) {
        BizLeaveImpl bizLeave = new BizLeaveImpl();    // 被代理的对象

        // 创建代理对象(创建的代理对象可以放在容器中缓存,后续调用时获取即可)
        BizLeaveImpl proxyObject = (BizLeaveImpl) new CGProxy().getProxyObject(bizLeave);

        proxyObject.doLeave("张三");

    }

    public static class CGProxy implements MethodInterceptor{

        private Object target;    // 被代理对象

        public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy proxy) throws Throwable {

            System.out.println("调用方法"+ arg1.getName());

            Object result = proxy.invokeSuper(arg0, arg2);

            return result;
        }

        public Object getProxyObject(Object target) {

            this.target = target;

            Enhancer enhancer = new Enhancer();

            // 设置父类
            enhancer.setSuperclass(this.target.getClass());

            // 设置回调(在调用父类方法时,回调 this.intercept())
            enhancer.setCallback(this);

            // 创建代理对象
            return enhancer.create();
        }
    }

} 

输出结果:

调用方法doLeave
张三办理请假

 jdk动态代理例子

 /**
 * 办理请假,这里需要实现接口,否则报错。
 */
class BizLeaveImpl implements BizLeave{
    public void doLeave(String name){
        System.out.println(name + "办理请假");
    }
}

interface BizLeave{
    public void doLeave(String name);
}

public class Zhangsan{

    public static void main(String[] args) {
        // 获取代理对象
        BizLeave bizLeave = (BizLeave) (new JdkProxy().newProxyInstance(new BizLeaveImpl()));
        bizLeave.doLeave("张三");
    }
    public static class JdkProxy implements InvocationHandler {

        private Object target;

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("调用方法"+method.getName());
            Object result = method.invoke(target, args);
            return result;
        }
        /**
         * 获取代理对象
         **/
        private Object newProxyInstance(Object targetObject){
            // 目标对象赋值
            this.target = targetObject;
            // 返回代理对象
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }

    }
}

测试一下