java 中的动态代理实现

这篇具有很好参考价值的文章主要介绍了java 中的动态代理实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 什么是代理模式

代理模式是常见的设计模式之一,顾名思义,代理模式就是代理对象具备真实对象的功能,并代替真实对象完成相应操作,并能够在操作执行的前后,对操作进行增强处理。(为真实对象提供代理,然后供其他对象通过代理访问真实对象)。

代理就是帮别人做事情,如:工厂的中介,中介负责为工厂招收工人,那么中介就是工厂的代理;客户通过商家购买东西,商家向厂家购买货物,商家就是工厂的代理 。

在开发中存在a类需要调用c类的方法,完成某一个功能,但是c禁止a调用。这时,可以在a和c之间创建一个b类代理,a类访问b类,b类访问c类。

代理模式就是为其他对象提供一种代理来控制这个对象的访问,在某些情况下一个对象不适合或不能直接引用另一个对象,而代理对象可以在客户类和目标对象直接起到中介的作用
 

代理有分为动态代理和静态代理

2. 什么是静态代理

由程序员创建或特定工具自动生成源代码,也就是在编译时就已经将接口,被代理类,代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成.

 缺点: 

1. 被代理对象增加,代理对象也要增加,导致代理数量过多

2. 被代理对象接口如有改动,其实现类都需要改动

/**
 * 订单接口类
 */
public interface OrderService {
    void save();
}
/**
 * 订单实现类
 */
public class OrderServiceImpl implements OrderService{

    @Override
    public void save() {
        System.out.println("保存订单信息 ...");
    }
}
/**
 * 代理对象
 */
public class ProxyOrderService implements OrderService {

    // 被代理的对象
    private OrderService orderService;

    public ProxyOrderService(OrderService orderService) {
        this.orderService = orderService;
    }

    @Override
    public void save() {
        System.out.println("代理前置处理 ...");
        // 执行被代理的对象的方法
        orderService.save();
        System.out.println("代理后置处理 ...");
    }
}
    // 执行
    public static void main(String[] args) {
        // 创建被代理对象
        OrderService orderService = new OrderServiceImpl();

        // 创建代理对象
        ProxyOrderService proxy = new ProxyOrderService(orderService);

        proxy.save();
    }

输出

java 中的动态代理实现

2. 什么是动态代理

代理类在程序运行时创建的代理方式被成为动态代理。 我们上面静态代理的例子中,代理类(ProxyOrderService )是自己定义好的,在程序运行之前就已经编译完成。然而动态代理,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类中的方法。

jdk 动态代理

/**
 * 订单接口类
 */
public interface OrderService {
    void save();
}


/**
 * 订单实现类
 */
public class OrderServiceImpl implements OrderService{

    @Override
    public void save() {
        System.out.println("保存订单信息 ...");
    }
}
/**
 *
 * 代理对象 实现 InvocationHandler
 * InvocationHandler 该类做方法拦截所用, 通过此类可以对目标方法进行增强
 */
public class ProxyOrderService implements InvocationHandler {

    private OrderService orderService;

    public ProxyOrderService(OrderService orderService) {
        this.orderService = orderService;
    }

    /**
     * 通过该方法的调用对目标对象进行增强
     * @param proxy  代理类代理的真实代理对象
     * @param method 执行的方法
     * @param args   执行方法的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理前置处理 ...");
        Object invoke = method.invoke(orderService, args);
        System.out.println("代理后置处理 ...");

        return invoke;
    }

    /**
     * ClassLoader loader   类加载器
     * Class<?>[] interfaces 代理对象类类型
     * InvocationHandler 处理类
     *
     * @param args
     */
    public static void main(String[] args) {
        ProxyOrderService proxyOrderService = new ProxyOrderService(new OrderServiceImpl());
        // 返回代理对象
        OrderService orderService =
                (OrderService) Proxy
                        .newProxyInstance(ProxyOrderService.class.getClassLoader(), new Class[]{OrderService.class}, proxyOrderService);
        orderService.save();
    }

}

执行结果

java 中的动态代理实现

 代理类源码java 中的动态代理实现

生成的代理类源码方法

    /**
     * 生成动态代理源码
     *
     * @param path 保存路径
     * @param var1 代理对象类类型
     */
    private static void saveProxyClass(String path, Class<?>[] var1) {
        byte[] $proxy1s = ProxyGenerator.generateProxyClass("$Proxy1", var1);
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(new File(path + "$Proxy1.class"));
            out.write($proxy1s);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

cglib 代理

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.7</version>
        </dependency>

/**
 * 订单接口类
 */
public interface OrderService {
    void save();
}

/**
 * 订单实现类
 */
public class OrderServiceImpl implements OrderService{

    @Override
    public void save() {
        System.out.println("保存订单信息 ...");
    }
}

/**
 * 实现 MethodInterceptor 重写 intercept
 *
 */
public class MyInterceptor implements MethodInterceptor {

    /**
     *
     * @param o 代理对象
     * @param method 被代理对象的方法
     * @param objects 方法入参
     * @param methodProxy 代理方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib代理方法执行之前 ...");
        Object o1 = methodProxy.invokeSuper(o, objects);
        System.out.println("cglib代理方法执行之后 ...");
        return o1;
    }

}

    public static void main(String[] args) {
        // 代理类class文件存入本地磁盘方便我们反编译查看源码
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "./code");

        // 通过CGLIB动态代理获取代理对象的过程
        Enhancer enhancer = new Enhancer();
        // 设置enhancer对象的父类
        enhancer.setSuperclass(OrderServiceImpl.class);
        // 设置enhancer的回调对象
        enhancer.setCallback(new MyInterceptor());
        // 创建代理对象
        OrderService orderService = (OrderServiceImpl) enhancer.create();
        orderService.save();
    }

运行结果

java 中的动态代理实现

Java动态代理和cglib比较
生成代理类技术不同
        java动态代理:jdk自带类ProxyGenerator生成class字节码
        cglib:通过ASM框架生成class字节码文件
生成代理类的方式不同
        java动态代理:代理类继承java.lang.reflect.Proxy,实现被代理类的接口
        cglib:代理类继承被代理类,实现net.sf.cglib.proxy.Factory
生成类数量不同
        java动态代理:生成一个proxy类
        cglib:生成一个proxy,两个fastclass类
调用方式不同
        java动态代理:代理类->InvocationHandler->反射调用被代理类方法
        cglib:代理类->MethodInterceptor->调用索引类invoke->直接调用被代理类方法文章来源地址https://www.toymoban.com/news/detail-468237.html

到了这里,关于java 中的动态代理实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • java中的静态代理、jdk动态代理以及CGLIB 动态代理

    代理模式是一种比较好理解的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能 那以下文章主要谈三种代理模式, 分别是静态代理,jdk的动态代理,cglib的动

    2024年02月11日
    浏览(41)
  • Java 代理模式详解,静态代理与动态代理的区别及优缺点

    代理模式是一种常用的设计模式,它允许通过引入一个代理对象来控制对目标对象的访问。在Java中,代理模式被广泛应用,它可以提供额外的功能,如权限检查、缓存、日志记录等,同时还能在不修改目标对象的情况下对其进行扩展。 代理模式(Proxy Pattern)是指通过代理对象

    2024年02月11日
    浏览(43)
  • 代理模式【静态代理和动态代理实现业务功能扩展】

    我们在不修改业务的情况下想要给它增加一些功能,这就需要使用代理模式。 我们不会在原有业务上直接修改,为了避免修改导致程序不可逆转的破坏。 三种角色:抽象角色-接口、真实角色-实现类和代理角色-代理类。 真实角色和代理角色继承的是同一个抽象角色接口!

    2024年02月16日
    浏览(32)
  • Java中的动态代理

    Java中常用的有两种动态代理方式,分别为:JDK动态代理和Cglib动态代理。 JDK动态代理是通过实现接口的方式完成动态代理。 Cglib动态代理是通过继承目标类或实现接口的方式完成动态代理。 JDK动态代理中最核心的就是Proxy类和InvocationHandler接口。 通过调用这个类中的静态方法

    2024年02月16日
    浏览(40)
  • JavaScript代理模式:如何实现对象的动态代理

    在JavaScript中,代理模式是一种常见的设计模式,它允许我们在不改变对象本身的情况下,通过代理对象来控制对象的访问。代理模式可以用于实现缓存、权限控制、远程调用等功能。 代理模式是指在访问对象时引入一定程度的间接性,因为这种间接性可以附加多种用途,所

    2024年02月11日
    浏览(41)
  • 代理模式 静态代理和动态代理(jdk、cglib)——Java入职第十一天

            一个类代表另一个类去完成扩展功能,在主体类的基础上,新增一个代理类,扩展主体类功能,不影响主体,完成额外功能。比如买车票,可以去代理点买,不用去火车站,主要包括静态代理和动态代理两种模式。 代理类中包含了主体类 无法根据业务扩展,每一次

    2024年02月10日
    浏览(48)
  • Java中的代理模式

    接口 目标类 代理类 测试 接口 目标类 动态代理类 测试 总结: 动态生成代理类 通过实现接口生成代理类(目标接口必须实现接口) 代理类是实现接口的方式 调用目标类使用反射调用 目标类调用本类方法只会代理一次 目标类 代理类 测试 总结 通过ASM第三方框架动态代理 无需接

    2024年02月15日
    浏览(35)
  • Java设计模式中的代理模式

    Java设计模式中的代理模式 代理模式是一种结构型设计模式,它提供了一个代理对象,以控制对其他对象的访问。代理可以充当中介,用于控制对真实对象的访问。 代码举例演示 静态代理: 动态代理 区别: 静态代理: 代理类在编译时就已经确定,并且需要为每个被代理的

    2024年01月25日
    浏览(42)
  • Java中的代理模式(一)

    大家好👋,我是极客涛😎,今天我们聊一聊java中的代理模式,话不多说,还是老思路,什么是代理模式,为什么要有代理模式,如何实现代理模式 在说java中的代理模式之前,我们可以先想一想生活的例子,这里也是一个加深自己对程序设计理解的一种学习方式,程序本质

    2024年01月24日
    浏览(35)
  • 【Java】jdk1.8 Java代理模式,Jdk动态代理讲解(非常详细,附带class文件)

       📝个人主页:哈__ 期待您的关注  想要学代理模式,我们就要先弄清一个概念 “什么是代理”? 在我们的现实生活中,你或许不少听过关于代理的名词,如:代理商。那什么又叫做代理商?让我一个词来形容就是 中间商。 举个例子,在你买二手房的时候,你一般不会直

    2024年04月15日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包