基于JDK的动态代理和基于CGLIB的代理异同

基于JDK的动态代理

基于jdk的动态代理,底层是依赖java反射来实现增强逻辑织入到业务逻辑里面的。Spring AOP在目标累实现接口的情况下,默认采用JDK的动态代理方式进行目标类的代理。下面来看看JDK动态代理的原理:

我们的目标类是Person,他实现了接口Voice,然后我们实现一个MyHandler,MyHandler持有Person,在调用invok的时候,利用反射机制先判断调用的方法是不是say,如果是,在方法请后织入增强逻辑。

public interface Voice {
    void say();
}
public class Person implements Voice {

    String name;

    public Person(String name) {
        this.name = name;
    }

    public void say() {
        System.out.println(name + " is saying hello!");
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyHandler implements InvocationHandler {

    private Object object;

    public MyHandler(Object object) {
        this.object = object;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object res = null;
        if (method.getName().equals("say")) {
            System.out.println("before call say method");
            res = method.invoke(object, args);
            System.out.println("after call say method");

        }
        return res;
    }
}
import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args) {
        Person p =new Person("cy");
        Voice v = (Voice) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Voice.class}, new MyHandler(p));
        v.say();
    }
}
xxxbefore call say method
cy is saying hello!
after call say method

Process finished with exit code 0

基于CGLIB的动态代理

基于CGLIB的动态代理,底层是利用ASM技术实现的,ASM动态生成目标类的子类的字节码。在子类中,将增强逻辑织入进去,父类负责业务逻辑,子类负责增强逻辑。由于需要继承,目标类不可以是final声明的类。

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class MyMethodInterceptor implements MethodInterceptor {


    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object res = null;

        if (method.getName().equals("say")) {
            System.out.println("before say hello!");
            res = methodProxy.invokeSuper(o, objects);
            System.out.println("after say hello!");
        }
        return res;
    }
}
import net.sf.cglib.proxy.Enhancer;


public class Main {



    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Dog.class);
        enhancer.setCallback(new MyMethodInterceptor());


        Dog dog = (Dog)enhancer.create();
        dog.say();


    }
}
before say hello!
the dog is saying hello!
after say hello!

Process finished with exit code 0

两种动态代理技术的对比

JDK动态代理基于CGLIB的动态代理
生成速度较快较慢,可以使用缓存技术解决这个问题
执行速度较慢较快
目标类是否需要实现接口需要不需要
目标类是否可以声明为final可以不可以
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值