4.16--设计模式之创建型之代理模式(总复习版本)---脚踏实地,一步一个脚印

news2024/10/7 6:45:35

1.代理对象
定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用,从而实现对真实对象的操作。
通俗的来讲代理模式就是我们生活中常见的中介

在代理模式中,代理对象主要起到一个中介的作用,用于协调与连接调用者(即客户端)和被调用者(即目标对象),在一定程度上降低了系统的耦合度,同时也保护了目标对象。 缺点是在调用者与被调用者之间增加了代理对象,可能会造成请求的处理速度变慢。

2.代理模式分为三类:

  1. 静态代理
  2. 动态代理
  3. CGLIB代理

结构图:

在这里插入图片描述

1.Subject:抽象角色,声明了真实对象和代理对象的共同接口;
2.Proxy:代理角色,实现了与真实对象相同的接口,所以在任何时刻都能够代理真实对象,并且代理对象内部包含了真实对象的引用,所以它可以操作真实对象,同时也可以附加其他的操作,相当于对真实对象进行封装。
3.RealSubject:真实对象,是我们最终要引用的对象

静态代理
静态代理模式由三个部分构成:

1.一个公共的接口
2.一个被代理角色
3.一个代理角色

1.创建公共的接口


//公共接口
public interface Rent {
    void renting();
}

2.创建被代理角色


//被代理对象
public class Corey implements Rent{
    //这是被代理对象!(房主)
    @Override
    public void renting() {
        System.out.println("Corey有房出租");
    }
}

3.创建代理角色

//代理对象(中介)
public class StaticProxyRent implements Rent{
    private Rent rent;

    public StaticProxyRent(Rent rent){
        this.rent = rent;
    }

    @Override
    public void renting() {
        System.out.println("向房客出租房屋");
        this.rent.renting();
        System.out.println("完成售后服务");
    }
}


  1. 创建测试类
public class StaticProxyTest {
    public static void main(String[] args) {
        Rent rent = new Corey();
        StaticProxyRent staticProxyRent = new StaticProxyRent(rent);
        staticProxyRent.renting();
    }
}


  1. 使用 JDK 的 Proxy 类实现动态代理
    1、 创建业务接口
public interface JdkProxyRent {
    void renting();
}

2、 创建接口实现类

public class JdkProxyCorey implements JdkProxyRent {
    @Override
    public void renting() {
        System.out.println("Corey 有房出租!");
    }
}
  1. 创建生成代理对象的工厂
//动态生成代理对象的工厂
public class JdkProxyFactory {

    //动态生成代理对象
    public static Object getProxyBean(Object target){
        Class clazz = target.getClass();
        MyAspect myAspect = new MyAspect();
        //在JDK中动态生成代理对象的方法
        return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() {
            //动态生成代理对象的方法
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                myAspect.before();
                Object obj =  method.invoke(target,args);
                myAspect.after();
                return obj;
            }
        });
    }
}


4.创建切面对象


public class MyAspect {
    public void before(){
        System.out.println("带领房客看房...签租房协议");
    }
    public void after(){
        System.out.println("售后服务");
    }
}


5.创建测试类

public class jdkProxyTest {
    public static void main(String[] args) {
        JdkProxyRent jdkProxyRent = new JdkProxyCorey();
        JdkProxyRent jdkProxyRent1 =(JdkProxyRent)JdkProxyFactory.getProxyBean(jdkProxyRent);
        jdkProxyRent1.renting();

    }
}


3.使用 CGLIB 实现动态代理
CGLIB(Code Generation Library)是一个高性能开源的代码生成包,它被许多框架所使用,其底层是通过使用一个小而快的字节码处理框架 ASM(Java 字节码操控框架)转换字节码并生成新的类。因此 CGLIB 要依赖于 ASM 的包。
JDK 的动态代理机制只能代理实现了接口的类,而对于没有实现接口的类就不能使用JDK 的 Proxy 类生成代理对象,cglib 是针对类来实现代理的,他的原理是对指定的目标类生成一个子类并通过回调的方式来实现增强,但因为采用的是继承,所以不能对 final 修饰的类进行代理。

1.添加 jar 包
cglib.jar
asm.jar

2.创建业务接口

public interface CglibProxyRent {
    void renting();
}

3.创建接口实现类


public class CglibProxyCorey implements CglibProxyRent {
    @Override
    public void renting() {
        System.out.println("Corey 有房出租");
    }
}

4.创建生成代理对象的工厂

public class CglibProxyBeanFactory {
    public static Object getProxyBean(CglibProxyRent rent){
        CglibMyAspect myAspect = new CglibMyAspect();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(rent.getClass());
        enhancer.setCallback(new MethodInterceptor() {

            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                myAspect.before();
                Object obj = method.invoke(rent,objects);
                myAspect.after();
                return obj;
            }
        });
        return enhancer.create();
    }
}

  1. 创建切面
public class CglibMyAspect {
    public void before(){
        System.out.println("带领客户看房,签订租房协议");
    }

    public void after(){
        System.out.println("售后服务");
    }
}
  1. 创建测试类
public class Test {
    public static void main(String[] args) {
        CglibProxyRent rent = new CglibProxyCorey();
        CglibProxyRent rent1 = (CglibProxyRent) CglibProxyBeanFactory.getProxyBean(rent);
        rent1.renting();
    }
}


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

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

相关文章

初识Docker并在linux完成安装

文章目录一、 初识Docker1.1 简介1.2 Docker和虚拟机的异同1.3 Docker架构二、 DockerHub三、Docker的安装一、 初识Docker 1.1 简介 Docker是一种开源的容器化平台,可以让开发者在容器中打包、发布、运行和管理应用程序。它使用轻量级的容器来隔离应用程序和它们的…

Scrapy爬虫基本使用与股票数据Scrapy爬虫

Scrapy爬虫的常用命令 scrapy命令行格式 红色是常用的三种命令 为什么Scrapy采用命令行创建和运行爬虫? 命令行(不是图形界面)更容易自动化,适合脚本控制 本质上,Scrapy是给程序员用的,功能&#xff08…

vue打包之后,可以进行修改配置后端地址、端口等信息方法

前言 用vue-cli构建的项目通常是采用前后端分离的开发模式,也就是前端与后台完全分离,此时就需要将后台接口地址打包进项目中,但是,难道我们只是改个接口地址也要重新打包吗?当然不行了,那就太麻烦了&#…

支付宝沙箱环境+SpringBoot+内网穿透整合开发

目录 1.查看沙箱账号 2.内网穿透 3.沙箱环境整合SpringBoot开发 下面我将以实际案例详细介绍如何使用沙箱环境进行支付宝支付对接的开发 1.查看沙箱账号 首先什么是沙箱账号? 沙箱账号是指在支付宝沙箱环境中创建的测试账户,用于模拟真实的支付流程…

The 2022 ICPC Asia Xian Regional Contest

题目顺序大致按照难度排序。 F. Hotel 现在酒店中有单人间和双人间,价格分别是c1,c2,现在有n个队,每队三个人,性别分别用字母表示,当两个人性别相同且在同一个队时,他们可以住在双人间中。求最…

【跑跑Github开源项目系列】基于YOLO和Streamlit的车辆识别系统demo

【跑跑Github开源项目系列】基于YOLO和Streamlit的车辆识别系统demo写在前面环境配置创建虚拟环境安装库项目运行写在前面 相信很多朋友跟我一样在github等平台上偷代码 (读书人的事怎么能叫偷呢) 的时候会发现伟大且无私的作者虽然开源了代码但是readme文件该写的没写&#x…

2023TYUT移动应用软件开发程序设计和填空

目录 程序设计 程序设计1:根据要求设计UI,补充相应布局文件,即.xml文件 程序设计2:根据要求,补充Activity.java文件 程序填空 说明: 程序设计 程序设计1:根据要求设计UI,补充相应布局文件,即.xml文件…

【C++初阶】第十篇:list模拟实现

文章目录一、list的模拟实现三个类及其成员函数接口总览结点类的模拟实现迭代器类的模拟实现迭代器类的模板参数说明迭代器operator->的重载迭代器模拟实现代码list的模拟实现无参构造函数带参构造拷贝构造函数赋值运算符重载函数析构函数begin和endinserteraselist的迭代器…

WordPress添加阿里云OSS对象云储存配置教程

背景:随着页面文章增多,内置图片存储拖连网站响应速度,这里对我来说主要是想提升速度 目的:使用第三方云存储作为图片外存储(图床),这样处理可以为服务器节省很多磁盘空间,在网站搬家的时候减少文件迁移的工…

【数据结构】堆(笔记总结)

👦个人主页:Weraphael ✍🏻作者简介:目前学习C和算法 ✈️专栏:数据结构 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞&…

MySQL--数据库基础--0406

目录 1.什么是数据库? 2. 基本使用 2.1 连接服务器 2.2 数据库的操作在Linux中的体现 2.3 使用案例 3.服务器,数据库,表关系 4.数据逻辑存储 5.SQL的分类 6.存储引擎 1.什么是数据库? 数据库和文件 文件或者数据库&…

OK-MX93开发板-实现Web页面无线点灯

上篇文章:i.MX9352——介绍一款多核异构开发板,介绍了OK-MX9352开发板的基础硬件功能。 本篇来使用OK-MX9352开发板,通过Web界面进行点灯测试,最终的效果如下: 在进行代码编写之前,先在Ubuntu虚拟机上把这…

对比损失Contrastive Loss(CVPR 2006)原理解析

paper:http://yann.lecun.com/exdb/publis/pdf/hadsell-chopra-lecun-06.pdf 本文提出的对比损失contrastive loss被广泛应用于自监督模型中,但最初对比损失是作为一个特征降维方法而提出的。 摘要 降维是学习一种映射关系,通过这种映射关…

day10 线程池及gdb调试多线程

目录 线程池的概念 概念: 必要性: 线程池的基本结构: 线程池的实现 完整代码 线程的GDB调试 线程池的概念 概念: 通俗的讲就是一个线程的池子,可以循环的完成任务的一组线程集合; 必要性&#xff…

【软件工程】为什么要选择软件工程专业?

个人主页:【😊个人主页】 文章目录前言软件工程💻💻💻就业岗位👨‍💻👨‍💻👨‍💻就业前景🛩️🛩️🛩️工作环…

趣谈之什么是 API 货币化?

本文介绍了 API 货币化和 APISIX 实现 API 货币化方法。 作者刘维,API7.ai 技术工程师,Apache APISIX Contributor 原文链接 什么是 API 货币化 想象你开发并部署了一个服务,能够搜集你所在城市所有超市的打折和优惠信息,其他的…

C生万物 | 校招热门考点 —— 结构体内存对齐

文章目录一、前言结构体偏移量计算:offsetof二、规则介绍例题的分解与细说三、习题演练1、练习①2、练习②四、为什么存在内存对齐?1、平台原因(移植原因)2、性能原因五、如何修改默认对齐数六、实战演练✍一道百度笔试题: offsetof 宏的实现&#x1f4…

深度学习基础篇之深度神经网络(DNN)

神经网络不应该看做是一个算法,应该看做是一个特征挖掘方法。在实际的业界发展过程中,数据的作用往往大于模型,当我们把数据的隐藏特征提取出来之后,用很简单的模型也能预测的很好。 神经网络模型由生物神经中得到启发。在生物神…

【Linux】Makefile的简述

目录 前言: 一、Makefile的规则 二、Makefile的函数语法 (1)通配符pattern ​(2) 删除clean ​(3) 立即变量、延时变量 (4) Makefile常用函数 3-1.Makefile要达到…

第11章_常用类和基础API

第11章_常用类和基础API 讲师:尚硅谷-宋红康(江湖人称:康师傅) 官网:http://www.atguigu.com 本章专题与脉络 1. 字符串相关类之不可变字符序列:String 1.1 String的特性 java.lang.String 类代表字符串…