设计模式-代理模式使用教程

在 Java 中实现代理模式通常包括两种方式:静态代理和动态代理。静态代理是在编译时就已经确定代理类和真实对象的关系,而动态代理则是在运行时动态生成代理类。下面,我会分别解释如何在项目中实践这两种代理模式。

静态代理

  1. 定义接口:首先定义一个接口,声明你想要代理的方法。
1public interface IService {
2    void serve();
3}
  1. 实现接口:创建一个真实对象类,实现上述接口。
1public class RealService implements IService {
2    @Override
3    public void serve() {
4        System.out.println("Serving something important...");
5    }
6}
  1. 创建代理类:然后创建一个代理类,同样实现这个接口,并在内部持有一个真实对象的引用,代理类可以在调用真实对象的方法前后添加额外的逻辑。
1		public class ProxyService implements IService {
2    private IService realService;
3
4    public ProxyService(IService realService) {
5        this.realService = realService;
6    }
7
8    @Override
9    public void serve() {
10        System.out.println("Proxy before serving...");
11        realService.serve();
12        System.out.println("Proxy after serving...");
13    }
14}
  1. 使用代理:在客户端代码中,使用代理类来替代真实对象。
1		public class Client {
2    public static void main(String[] args) {
3        IService realService = new RealService();
4        IService proxyService = new ProxyService(realService);
5        
6        proxyService.serve();
7    }
8}

动态代理

在Java中,动态代理通常是通过java.lang.reflect.Proxy类和
java.lang.reflect.InvocationHandler接口来实现的。

  1. 定义接口:这一步和静态代理相同,你需要一个接口。
1public interface IService {
2    void serve();
3}
  1. 实现接口:创建真实对象类,实现接口。
1public class RealService implements IService {
2    @Override
3    public void serve() {
4        System.out.println("Serving something important...");
5    }
6}
  1. 创建调用处理器:创建一个InvocationHandler,它定义了代理实例的调用处理程序。
1public class ProxyInvocationHandler implements InvocationHandler {
2    private Object target;
3
4    public ProxyInvocationHandler(Object target) {
5        this.target = target;
6    }
7
8    @Override
9    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
10        System.out.println("Invoking method: " + method.getName());
11        Object result = method.invoke(target, args);
12        System.out.println("Method executed: " + method.getName());
13        return result;
14    }
15}
  1. 使用动态代理:在客户端代码中,创建真实对象的代理实例,并通过它调用方法。
1public class Client {
2    public static void main(String[] args) {
3        IService realService = new RealService();
4        IService proxyService = (IService) Proxy.newProxyInstance(
5            realService.getClass().getClassLoader(),
6            new Class[] { IService.class },
7            new ProxyInvocationHandler(realService)
8        );
9        
10        proxyService.serve();
11    }
12}

在上面的动态代理例子中,Proxy.newProxyInstance方法创建了一个实现了IService接口的代理实例,所有对该代理实例的方法调用都会被转发到
ProxyInvocationHandler.invoke方法。

这些是代理模式在Java项目中的基本实践。在实际的项目中,代理模式常常用于访问控制、懒加载、日志记录、性能计数、事务处理等场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/732377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML5基础2

drag 可以把拖放事件拆分成4个步骤 设置元素为可拖放。为了使元素可拖动&#xff0c;把 draggable 属性设置为 true 。 <img draggable"true"> 拖动什么。ondragstart 和 setData() const dragestart (ev)>{ev.dataTransfer.setData(play,ev.target.id)} …

Pytorch线性回归实现(原理)

设置梯度 直接在tensor中设置 requires_gradTrue&#xff0c;每次操作这个数的时候&#xff0c;就会保存每一步的数据。也就是保存了梯度相关的数据。 import torch x torch.ones(2, 2, requires_gradTrue) #初始化参数x并设置requires_gradTrue用来追踪其计算历史 print(x…

软考笔记--系统架构评估

系统架构评估是在对架构分析、评估的基础上&#xff0c;对架构策略的选取进行决策。它利用数据或逻辑分析技术&#xff0c;针对系统的一致性&#xff0c;正确性&#xff0c;质量属性&#xff0c;规划结果等不同方面&#xff0c;提供描述性&#xff0c;预测性和指令性的分析结果…

C#协变与逆变:解锁高级编程技巧,轻松提升代码性能

文章目录 协变协变接口的实现逆变里氏替换原则 协变 协变概念令人费解&#xff0c;多半是取名或者翻译的锅&#xff0c;其实是很容易理解的。 比如大街上有一只狗&#xff0c;我说大家快看&#xff0c;这有一只动物&#xff01;这个非常自然&#xff0c;虽然动物并不严格等于…

【Spring Boot `@Autowired` Annotation】

文章目录 1. 使用Qualifier注解2. 使用Primary注解3. 手动注入&#xff08;较少推荐&#xff09; 在Spring Boot中&#xff0c;Autowired注解用于自动装配bean。默认情况下&#xff0c;它按照类型进行装配。当存在多个相同类型的bean时&#xff0c;就会出现以下错误&#xff1a…

AndroidStudio跑马灯实现

在activity_main.xml中编写如下代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_h…

题目 1971: 外出旅游

题目描述: 佳佳带着f个水果和m元钱出去玩&#xff0c;每天房屋的租金为x元&#xff0c;佳佳每天早上必须吃一个水果&#xff0c;佳佳通过询问商店的服务人员 得到了水果的价格&#xff0c;每个水果售卖p元。请你计算一下佳佳最多可以在外面待多长时间&#xff1f; 代码: pac…

meta元数据元素

文章目录 元数据Metadatameta标签的四种使用方式meta的属性meta使用示例 HTML <meta> 元素表示那些不能由其他 HTML标签&#xff08; <style>、 <script>等&#xff09;表示的元数据信息。 元数据Metadata Metadata元数据&#xff0c;简单地来说就是描述…

Linux——权限的理解

Linux——权限的理解 文章目录 Linux——权限的理解一、shell命令以及运行原理二、Linux权限的概念切换用户对指令提权 三、Linux权限管理1. 文件访问者的分类&#xff08;人&#xff09;2. 文件类型和访问权限&#xff08;事物属性&#xff09;文件类型基本权限文件权限值的表…

Linux系统安装及简单操作

目录 一、Linux系统安装 二、Linux系统启动 三、Linux系统本地登录 四、Linux系统操作方式 五、Linux的七种运行级别&#xff08;runlevel&#xff09; 六、shell 七、命令 一、Linux系统安装 场景1&#xff1a;直接通过光盘安装到硬件上&#xff08;方法和Windows安装…

小白跟做江科大51单片机之DS1302可调时钟

原理部分 1.DS1302可调时钟介绍 单片机定时器主要占用CPU时间&#xff0c;掉电不能继续运行 图1 2.原理 图2 内部有寄存器&#xff0c;寄存的时候以时分秒寄存&#xff0c;以通信协议实现数据交互&#xff0c;就可以实现对数据进行访问和读写 3.主要寄存器定义 CE芯片使能…

js对象 静态方法和实例方法

求下面代码的输出结果&#xff1a; 首先先分析一下上面各函数&#xff1a; Person.say function(){console.log("a")} 第一个say()方法是定义在Person函数身上的&#xff0c;我们如果想使用这个方法&#xff0c;可以通过Person().say()来调用 this.say function()…

【Docker7】Docker安全及https安全认证

Docker安全及https安全认证一、Docker 容器与虚拟机的区别1、隔离与共享2、性能与损耗3、不同点 二、Docker 存在的安全问题1、Docker 自身漏洞2、Docker 源码问题 三、Docker 架构缺陷与安全机制1、容器之间的局域网攻击2、DDoS 攻击耗尽资源2.1 什么叫CC攻击&#xff1f;什么…

Python实现汉诺塔演示程序

Python实现汉诺塔演示程序 汉诺塔问题 一个板子上有三根柱子以及一些大小各不相同的圆盘。我们分别把这三根柱子叫做起始柱A、辅助柱B及目标柱C&#xff0c;汉诺塔移动圆盘的规则如下&#xff1a; 把起始柱A上所有的圆盘都移动到C柱&#xff0c;且在移动过程中始终保持圆盘从…

先进电机技术 —— 伺服驱动器与变频器

一、变频器与伺服驱动器发展趋势 在近年来的技术发展中&#xff0c;变频器和伺服驱动器均呈现出显著的先进性提升和技术融合趋势&#xff0c;以下是一些主要的发展方向&#xff1a; ### 变频器的发展趋势&#xff1a; 1. **智能化与网络化**&#xff1a; - 高级变频器集成…

react hook:useMemo

useMemo在每次重新渲染的时候能够缓存计算的结果。 在初次渲染时&#xff0c;useMemo 返回调用 calculateValue 的结果。 在接下来的渲染中&#xff0c;如果依赖项没有发生改变&#xff0c;它将返回上次缓存的值&#xff1b;否则将再次调用 calculateValue&#xff0c;并返回最…

Git本地新项目推送到远程仓库

假设开发了一个新项目&#xff0c;想推送到远程&#xff0c;具体的操作方式和命令如下&#xff1a; &#xff08;使用 git bash&#xff09; 1、切到项目目录中 2、初始化git仓库并在本地提交 //初始化git仓库 git init//将当前目录下的文件添加到仓库&#xff08;缓冲区&…

【知识分享】自动化测试首选接口自动化?

在分层测试的“金字塔”模型中&#xff0c;接口测试属于第二层服务集成测试范畴。 相比UI自动化测试而言&#xff0c;接口自动化测试收益更大&#xff0c;且容易实现&#xff0c;维护成本低&#xff0c;有着更高的投入产出比。因此&#xff0c;项目开展自动化测试的首选一般为接…

Python 基础语法:基本数据类型(字符串)

在日常生活中&#xff0c;我们经常会用文字来记录事物的名称、或记录事情的发展过程等&#xff0c;这些文字类型的数据&#xff0c;就叫做字符串。在未来的写代码的工作中&#xff0c;无论你从事的是哪个方面的编程&#xff0c;字符串操作必不可少&#xff0c;非常重要。 1 字…

linux系统安装docker

docker安装 docker安装自带源安装docker版本和官方源安装国内源安装新版docker生产docker的环境配置登入登出docker hub国内镜像源 docker安装 自带源安装 CentOS 7 中 Docker 的安装: Docker 软件包已经包括在默认的 CentOS-Extras 软件源(联网使用centos7u2自带网络Yum源)里…