栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java基础之动态代理机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java基础之动态代理机制

        在介绍动态代理之前,先了解一下什么叫静态代理。

        静态代理与动态代理都是代理,代理是对原功能的增强。

静态代理

        示例代码

public interface Person {
    
    void rentHouse();
}


class RentSeeker implements Person {
    @Override
    public void rentHouse() {
        System.out.println("我想租个大房子");
    }
}


class HouseAgent implements Person {

    private Person person;

    HouseAgent(Person person) {
        this.person = person;
    }

    @Override
    public void rentHouse() {
        person.rentHouse();
        System.out.println("我是房屋中介,我来带您看房");
    }
}

class Test {
    public static void main(String[] args) {
        // 寻租人通过房租中介租房
        new HouseAgent(new RentSeeker()).rentHouse();
    }
}

        结果

 

         类图

         缺点:每次新增一个对象类型的时候,我们都需要重新实现一个代理类。代码重用性差。

动态代理

        静态代理与动态代理的区别主要在于动态代理是在运行时动态生成的,在编译完成后没有具体的class文件,是在运行时动态生成并加载到JVM中,而静态代理的代理类是个具体的class文件。

        动态代理主要分为两种:CGLIB动态和JDK动态代理

        JDK动态代理

                我们先将上面的示例用JDK动态代理实现一遍

public interface Person {
    
    void rentHouse();
}


class RentSeeker implements Person {
    @Override
    public void rentHouse() {
        System.out.println("我想租个大房子");
    }
}


class Test {
    public static void main(String[] args) {
        // 寻租人通过房租中介租房
//        new HouseAgent(new RentSeeker()).rentHouse();
        RentSeeker rentSeeker = new RentSeeker();

        Person p = (Person) Proxy.newProxyInstance(RentSeeker.class.getClassLoader(),
                new Class[]{Person.class}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object o = method.invoke(rentSeeker, args);

                System.out.println("我是房屋中介,我来带您看房");
                return o;
            }
        });

        p.rentHouse();
    }
}

                CGLIB动态代理

                        CGLIB是一个第三方类库,运行时动态生成一个子类对象来实现对目标对象功能的扩展。

同样的例子再使用cglib实现一遍。

public class CgLibTest {

    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(RentSeeker.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                Object o = proxy.invokeSuper(obj, args);
                System.out.println("我是房屋中介,我来带您看房");
                return o;
            }
        });

        RentSeeker sample = (RentSeeker) enhancer.create();
        sample.rentHouse();
    }
}


class RentSeeker {
    public void rentHouse() {
        System.out.println("我想租个大房子");
    }
}

总结

        看例子就能看出来,JDK动态代理需要被代理类实现一个或多个接口,而CGLIB不需要。

        动态代理使用反射API操作,生成类比较高效,CGLIB使用ASM框架对字节码操作,在类的执行过程中比较高效。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/686305.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号