专业的编程技术博客社区

网站首页 > 博客文章 正文

jdk动态代理和cglib动态代理实现及区别

baijin 2024-09-04 02:03:23 博客文章 14 ℃ 0 评论

代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。

代理模式又分为:静态代理、jdk动态代理、cglib动态代理。由于静态代理会产生过多的代理类,一旦接口增加方法,目标对象与代理对象都要进行修改,不易维护。而动态代理是动态地在内存中构建代理对象,从而实现对目标对象的代理功能,接口增加方法时代理对象不受影响 。

jdk动态代理实现

接口

public interface IPerson {

    void eat();

    void sleep();

}

代理类

public class Person implements IPerson{

    @Override
    public void eat(){
        System.out.println("吃饭中......");
    }

    @Override
    public void sleep(){
        System.out.println("睡觉中......");
    }

}

方法调用处理器类,拦截方法调用

public class PersonInvocationHandler implements InvocationHandler {
    private Object target;

    public PersonInvocationHandler(Object target){
        this.target = target;
    }

    /**
     *
     * @param proxy 被代理实例对象
     * @param method Method实例对应于在代理实例上调用的接口方法。
     * @param args 一个对象数组,包含在代理实例的方法调用中传递的参数值,如果接口方法不接受参数,则为空。
     * @return Object 代理方法的执行结果
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{

        System.out.println("start");
        Object result = method.invoke(target, args);
        System.out.println("end");

        return result;
    }

}

测试

public class JDKAopTest {

    @Test
    public void test(){
        IPerson target = new Person();
        IPerson proxy = (IPerson) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new PersonInvocationHandler(target));
        proxy.eat();
        proxy.sleep();
    }

}

cglib动态代理

方法拦截器

public class PersonMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable{

        System.out.println("start");
        Object result = methodProxy.invokeSuper(o, objects);
        System.out.println("end");

        return result;
    }

}

测试

public class CglibAopTest {

    @Test
    public void test(){
        Person proxy = (Person) Enhancer.create(Person.class, 
						new PersonMethodInterceptor());
        proxy.eat();
        proxy.sleep();
    }

}

区别

1.JDK动态代理是实现了被代理对象的接口,Cglib是继承了被代理对象。

2.JDK和Cglib都是在运行期生成字节码,JDK是直接写Class字节码,Cglib使用ASM框架写Class字节码,Cglib代理实现更复杂,生成代理类比JDK效率低。

3.JDK调用代理方法,是通过反射机制调用,Cglib是通过FastClass机制直接调用方法,Cglib执行效率更高。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表