Java的三种代理模式简述

Java的三种代理模式简述

Java的三种代理模式为静态代理、动态代理和CGLIB代理。

一、静态代理

静态代理指的是代理对象在编译期已经确定的情况下所使用的代理模式。代理类与委托类实现了相同的接口,代理类对目标对象进行了包装,所以在调用目标对象时需要通过代理对象来执行。静态代理在性能方面较差,但是实现较为简单,常用于简单业务场景。

示例:

interface Subject {
    void request();
}

class RealSubject implements Subject{

    @Override
    public void request() {
        System.out.println("RealSubject request.");
    }
}

class ProxySubject implements Subject{

    private RealSubject realSubject;

    public ProxySubject(RealSubject realSubject){
        this.realSubject = realSubject;
    }

    @Override
    public void request() {
        System.out.println("ProxySubject request.");
        realSubject.request();
    }
}

public class Test {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        ProxySubject proxySubject = new ProxySubject(realSubject);
        proxySubject.request();
    }
}

二、动态代理

动态代理指的是在运行时对目标对象进行包装的代理模式,相比于静态代理,动态代理无需手动编写代理类,可根据目标对象的接口,动态的创建代理对象,并在代理对象中动态的处理方法调用、参数校验等逻辑。由于动态代理是在运行时创建的代理对象,所以性能较静态代理有所提升。常用于需要动态创建代理对象的场景。

示例:

interface Subject {
    void request();
}

class RealSubject implements Subject{

    @Override
    public void request() {
        System.out.println("RealSubject request.");
    }
}

class DynamicProxy implements InvocationHandler{

    private Object target;

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

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("DynamicProxy before.");
        Object result = method.invoke(target, args);
        System.out.println("DynamicProxy after.");
        return result;
    }
}

public class Test {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        DynamicProxy dynamicProxy = new DynamicProxy(realSubject);
        Subject proxySubject = (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), dynamicProxy);
        proxySubject.request();
    }
}

三、CGLIB代理

CGLIB代理是一种针对类来实现代理的方式,通过生成目标对象的子类来实现代理逻辑。使用CGLIB代理时,被代理对象无需实现任何接口,因为生成的代理类是继承于目标对象的子类,所以可直接操作目标对象的全部属性和方法。由于采用字节码生成技术,CGLIB代理的性能通常比JDK动态代理性能更高。常用于需要代理类的场景。

示例:

class RealSubject {

    public void request() {
        System.out.println("RealSubject request.");
    }
}

class CglibProxy implements MethodInterceptor{

    public Object createProxy(Class<?> targetClass){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(targetClass);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("CglibProxy before.");
        Object result = methodProxy.invokeSuper(o, objects);
        System.out.println("CglibProxy after.");
        return result;
    }
}

public class Test {
    public static void main(String[] args) {
        CglibProxy cglibProxy = new CglibProxy();
        RealSubject proxySubject = (RealSubject)cglibProxy.createProxy(RealSubject.class);
        proxySubject.request();
    }
}

以上就是Java中三种代理模式的详细介绍及示例。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java的三种代理模式简述 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • 一文带你了解Qt中槽的使用

    一文带你了解Qt中槽的使用 引言 在Qt中,槽(slot)是一种重要的机制,它能够帮助我们实现与用户交互的各种功能,包括连接按钮点击事件、接收用户输入、处理定时器事件等等。本文将通过介绍槽的定义、声明及连接方式,来带领读者深入了解Qt中槽的使用。 槽的定义及声明 在Qt中,槽被定义为一个成员函数,其格式如下: void 槽的名称(参数); 其中,参数可以是任…

    other 2023年6月26日
    00
  • canvas动画库createjs之easeljs(上篇)

    以下是关于“canvas动画库createjs之easeljs(上篇)”的完整攻略,包括基本概念、解决方法、示例说明和注意事项。 基本概念 EaselJS是CreateJS中的一个模块,是一个用于HTML5 Canvas的JavaScript库,可以帮助开发者快速创建交互式图形和动画。EaselJS提供了一组易于使用的API,可以轻松地创建形状、文本、位图、…

    other 2023年5月7日
    00
  • pycharm配置文件有什么用? PyCharm导入导出配置文件的技巧

    PyCharm是一种流行的Python集成开发环境(IDE),可以用于开发各种Python项目。PyCharm有一个强大的配置框架,可以让用户对其进行高度定制。在本文中,我们将详细介绍PyCharm配置文件的作用以及如何导入导出配置文件。 PyCharm配置文件的作用 PyCharm配置文件是一组存储在本地计算机中的文件,它们记录了PyCharm的所有设置。…

    other 2023年6月25日
    00
  • CentOS7环境下gcc(版本10.2.0)升级详细过程

    下面我将针对“CentOS7环境下gcc(版本10.2.0)升级详细过程”进行完整的讲解攻略。 准备工作 在进行gcc升级之前,我们需要先安装一些必要的依赖库和工具: sudo yum install -y gcc gcc-c++ glibc-devel glibc-static libstdc++-devel zlib-devel tar wget 升级过…

    other 2023年6月26日
    00
  • php根据用户名和手机号查询是否存在手机号码

    如果要根据用户名和手机号查询是否存在手机号码,可以通过以下步骤实现: Step 1: 连接数据库 首先,需要连接到MySQL数据库,可以使用MySQLi或PDO扩展。以下是一个示例连接到MySQL数据库的代码片段: $servername = "localhost"; // 数据库服务位于本地 $username = "user…

    other 2023年6月27日
    00
  • R语言-图形初阶

    R语言是一种用于数据分析和可视化的编程语言。在R语言中,图形是一种非常重要的数据可视化方式。本文将介绍R语言中图形初阶的完整攻略,包括绘制基本图形、添加注释和标签、设置图形属性等内容,并提供两个示例说明。 1. 绘制基本图形 在R语言中,我们可以使用plot()函数来绘制基本图形,例如散点图、折线图、柱状图等。下面是一个绘制散点图的示例: # 创建数据 x …

    other 2023年5月5日
    00
  • MybatisPlus使用代码生成器遇到的小问题(推荐)

    以下是使用MyBatis-Plus代码生成器遇到的小问题的完整攻略: MyBatis-Plus使用代码生成器遇到的小问题 问题1:生成的实体类字段命名不符合预期 有时候,使用代码生成器生成的实体类字段命名可能不符合预期,例如使用了下划线分隔的命名方式。解决这个问题的方法是使用@TableField注解来指定数据库字段和实体类字段的映射关系。示例代码如下: @…

    other 2023年10月14日
    00
  • 条件数据库Android:sqllite的简单使用

    下面是“条件数据库Android:sqllite的简单使用”的完整攻略。 1. 前言 SQLite是一款功能强大的嵌入式关系型数据库,它被广泛应用在各个领域当中,而在Android中,SQLite是Android中的默认数据库,因此它也被广泛地应用在Android项目中。本篇文章将介绍在Android开发中如何使用SQLite数据库。 2. 实现SQLite…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部