(4)spring常用模式--------原型模式

设计模式 6 - 原型模式及spring源码案例分析 目录 原型模式 1. 原型模式的引入 2. 原型模式的介绍和使用场景 3. 原理结构图UML图 4. 代码演示 5. 原型模式在spring中的使用 6.深拷贝的实现方式 7. 小结 原型模式 博主一句话总结(非准确):原型模式是一种创建下的设计模式,用于创建重复的对象,保证性能,在进行深拷贝时,可能会造成复杂的代码,同时需要为每一个类配备一个克隆方法,对于已经存在的类来说得修改源代码,这违背了ocp原则。 1. 原型模式的引入 原型模式,Java中的Object类是所.. 阅读详情

(4)spring常用模式--------原型模式

96 Mrsunup 关注

2018.09.02 12:38* 字数 807 阅读 48评论 0喜欢 0

原型模式就是从一个对象再创建另外一个可定制的对象, 而且不需要知道任何创建的细节。
所谓原型模式, 就是 Java 中的克隆技术, 以某个对象为原型。 复制出新的对象。 显然新的对象具备原型对象的特点, 效率高(避免了重新执行构造过程步骤)

在介绍原型模式之前,需要介绍浅拷贝和深拷贝的概念

1.浅拷贝和深拷贝的特点

浅拷贝:

  • ①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。
  • ②对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组、某个类的对象等,那么浅拷贝会进行引用传递,也就是只是将该成员变量的引用值(内存地址)复制一份给新的对象。因为实际上两个对象的该成员变量都指向同一个实例。在这种情况下,在一个对象中修改该成员变量会影响到另一个对象的该成员变量值。

深拷贝:

  • ①复制对象的所有基本数据类型的成员变量值
  • ②为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象,直到该对象可达的所有对象。也就是说,对象进行深拷贝要对整个对象图进行拷贝!

总结:
深拷贝对引用数据类型的成员变量的对象图中所有的对象都开辟了内存空间;而浅拷贝只是传递地址指向,新的对象并没有对引用数据类型创建内存空间

2.原型模式的浅拷贝和深拷贝的实现方式

  • 浅拷贝
     通过拷贝构造方法实现浅拷贝
     通过重写clone()方法进行浅拷贝
  • 深拷贝
     通过重写clone方法来实现深拷贝
     通过对象序列化实现深拷贝

接下来直接介绍浅拷贝和深拷贝的具体实现

在此之前,先给出原型模式的uml图

 

原型模式.png

3.原型模式的浅拷贝

浅度克隆目标的引用对象

/**
 * @Project: spring
 * @description:  浅度克隆目标的引用对象
 * @author: sunkang
 * @create: 2018-09-02 10:48
 * @ModificationHistory who      when       What
 **/
public class CloneableTarget   {

    public  String cloneName;

    public String cloneClass;
    
    public CloneableTarget( String cloneName,String cloneClass) {
        this.cloneName = cloneName;
        this.cloneClass = cloneClass;
    }
}

浅度克隆的对象的两种实现方式

/**
 * @Project: spring
 * @description:  克隆对象的浅拷贝
 *   1.通过构造方法来实现浅度拷贝
 *   2.通过clone()方法来实现浅度拷贝
 * @author: sunkang
 * @create: 2018-09-02 10:47
 * @ModificationHistory who      when       What
 **/
public class Prototype implements  Cloneable {

    public String name ;

    //拷贝的引用类型的成员变量
    public  CloneableTarget cloneableTarget;

    public Prototype(){

    }
    //1.通过构造方法来实现浅度拷贝
    public Prototype(Prototype prototype) {
        this.name = prototype.name;
        this.cloneableTarget = prototype.cloneableTarget;
    }
    //2.通过clone()方法来实现浅度拷贝
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

浅克隆的测试

/**
 * @Project: spring
 * @description: 浅度克隆对象的测试
 *
 * @author: sunkang
 * @create: 2018-09-02 10:51
 * @ModificationHistory who      when       What
 **/
public class CloneTest  {
    public static void main(String[] args) {
        Prototype  p = new Prototype();
        p.name="kang";
        p.cloneableTarget = new CloneableTarget("clone","CloneableTarget");
        System.out.println("原有的对象:"+p);
        System.out.println("原有的值对象引用:"+p.name.hashCode());
        System.out.println("原有的引用类型对象:"+p.cloneableTarget);
        try {
            //方式一 :通过重写clone()方法进行浅拷贝
            Prototype clonePrototype = (Prototype) p.clone();
            System.out.println("重写clone()克隆的对象:"+clonePrototype);
            System.out.println("重写clone()克隆的值对象引用:"+p.name.hashCode());
            System.out.println("重写clone()克隆的引用类型对象:"+ clonePrototype.cloneableTarget);

            //通过修改引用对象String类型的值,发现原有的对象的值没有发生改变,因为String对象是不可变对象,放在常量池中的,无法修改的
            //String 可以比较特殊,可以看做是值传递
            clonePrototype.name ="sun";
            System.out.println("原有对象的name:"+p.name);
            System.out.println("修改过的clone对象的name:"+clonePrototype.name);

            //方式二: 通过拷贝构造方法实现浅拷贝
            Prototype  constructClone=   new Prototype(p);
            System.out.println("构造方法克隆的对象:"+constructClone);
            System.out.println("构造方法克隆的值对象引用:"+constructClone.name.hashCode());
            System.out.println("构造方法克隆的引用类型对象:"+ constructClone.cloneableTarget);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

测试结果 : 可以发现引用类型的目标对象为同一个引用,string 对象可以看做是值传递,string对象是不可变的,克隆对象修改后的值对原有对象的值没有影响

浅克隆测试结果.png

4.原型模式的深拷贝

深度拷贝的目标引用对象

/**
 * 深度拷贝的目标引用对象
 */
public class DeepCloneableTarget implements Serializable,Cloneable {

    private  String cloneName;

    private String cloneClass;


    public DeepCloneableTarget(String cloneName, String cloneClass) {
        this.cloneName = cloneName;
        this.cloneClass = cloneClass;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

深度拷贝的实现拷贝的两种方式

/**
 * @Project: spring
 * @description: 深度拷贝的实现拷贝的两种方式
 * @author: sunkang
 * @create: 2018-09-02 11:19
 * @ModificationHistory who      when       What
 **/
public class DeepPrototype implements Serializable,Cloneable {

    public String name ;

    public  DeepCloneableTarget deepCloneableTarget;

    public DeepPrototype(){

    }
    //方式1 :通过重写clone方法来实现深拷贝  (引用对象多,这种方法比较繁琐)
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object deep = null;
        try {
            deep = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        DeepPrototype  deepPrototype = (DeepPrototype) deep;
        deepPrototype.deepCloneableTarget = (DeepCloneableTarget) deepPrototype.deepCloneableTarget.clone();
        return deepPrototype;
    }

    //方式2: 通过对象序列化实现深拷贝 (推荐)
    public Object deepClone(){
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        try {
             bos = new ByteArrayOutputStream();
             oos = new ObjectOutputStream(bos);
             oos.writeObject(this);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return  ois.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            if(oos !=null){
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(bos !=null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //输入流关闭省略
        }
        return null;
    }
}

深度拷贝的测试

/**
 * @Project: spring
 * @description:  深度拷贝的测试
 * @author: sunkang
 * @create: 2018-09-02 11:38
 * @ModificationHistory who      when       What
 **/
public class DeepCloneTest {

    public static void main(String[] args) {
        DeepPrototype p = new DeepPrototype();
        p.name="kang";

        p.deepCloneableTarget = new DeepCloneableTarget("clone","CloneableTarget");
        System.out.println("原有的对象:"+p);
        System.out.println("原有的值对象引用:"+p.name.hashCode());
        System.out.println("原有的引用类型对象:"+p.deepCloneableTarget);

        try {
            //方式一 :通过重写clone()方法进行浅拷贝
            DeepPrototype clonePrototype = (DeepPrototype) p.clone();
            System.out.println("clone()方法克隆的对象:"+clonePrototype);
            System.out.println("clone()方法克隆的值对象引用:"+p.name.hashCode());
            System.out.println("clone()方法克隆的引用类型对象:"+ clonePrototype.deepCloneableTarget);

            //方式二:  通过对象序列化实现深拷贝
            DeepPrototype  serializableClone= (DeepPrototype) p.deepClone();
            System.out.println("序列化方法克隆的对象:"+serializableClone);
            System.out.println("构序列化方法克隆的值对象引用:"+serializableClone.name.hashCode());
            System.out.println("序列化方法克隆的引用类型对象:"+ serializableClone.deepCloneableTarget);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

测试结果 :可以发现引用类型的成员变量的地址都是不一样的了,说明实现了深度拷贝

关于Spring 中常用的那些设计模式 Spring 中常用的设计模式 1、我们通常说的 23 中经典设计模式可以通过下表一目了然: 创建型 工厂方法模式(FactoryMethod)、抽象工厂模式(AbstractFactory)、 建造者模式(Builder)、原型模式(Prototype)、单例模式(Singleton)结构型适配器模式(Adapter)、桥接模式(Bridge)、组合模式(Composite)、 装饰器模式(... 阅读详情

相关推荐

实战指南:将MediaPipe封装为Windows DLL,实现C++/C#高效调用

在计算机视觉和多媒体处理领域,跨平台框架为开发者提供了强大的算法模型和计算能力。其核心原理在于通过预训练的机器学习模型和优化的计算图,实现对图像、视频流中特定目标(如人脸、手势、姿态)的实时检测与分析。这项技术的价值在于能够将复杂的AI能力模块化,降低应用开发门槛。在实际工程实践中,为了突破特定语言生态的限制并优化部署流程,开发者常需将核心功能封装成独立的库。例如,将Google的MediaPipe框架封装为Windows动态链接库(DLL),就是一个典型的工程实践。此举能有效解决语言壁垒和部署简化问题,使

weixin_28691741的博客 360

Spring中常用的设计模式:原型模式

文章目录定义模式分析模式优缺点分析原型模式的实际应用案例 定义 原型模式:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。 模式分析 在原型模式结构中定义了一个抽象原型类,所有的Java类都继承自java.lang.Object,而Object类提供一个clone()方法,可以将一个Java对象复制一份。因此在Java中可以直接使用Object提供的clone()方法来实现对...

蓝田日暖玉生烟 4386

RK3568下YT8531/YT8521 PHY移植避坑指南:RGMII与设备树详解

嵌入式Linux网络调试中,PHY芯片作为MAC与物理介质之间的桥梁,其驱动配置直接影响网络稳定性。RGMII接口的延时补偿、PHY地址设定以及复位时序是设备树配置中的关键环节,稍有差错便会出现链路已通却无法通信的现象。通过理解PHYLIB框架与mdio总线枚举原理,开发者可以快速定位寄存器级故障。在RK3568等工业级平台中,裕太微YT8531/YT8521凭借高性价比与内核主线支持,成为替代传统方案的热门选择。从设备树模板、内核配置到常见坑点,系统梳理千兆以太网PHY的移植与调试方法,帮助开发者少走弯路

weixin_29189381的博客 212

【设计模式】3、原型模式、浅拷贝、深拷贝

1、传统方式的优缺点 优点是比较好理解,简单易操作 在创建新的对象时,总是需要重新获取原始对象的属性,如果创建的对象过多,效率不高。 总是需要重新初始化对象,而不是动态的获取对象运行时的状态。 代码展示: public class Student { private String id; private String name; public Student(...

芝兰生于深谷,不以无人而不芳 732

Nvidia Isaac Sim安装与配置 入门教程 2024(2)

Isaac Sim 安装和配置教程将指导用户完成从下载软件到设置和运行仿真的全过程。教程内容包括安装必要的依赖项、配置系统环境、配置Omniverse环境以及调试和优化仿真环境的步骤。通过详细的操作步骤和图文并茂的说明,用户可以快速上手 Isaac Sim,构建出高质量的机器人仿真环境,实现其研究和应用目标。

m0_56661101的博客 2万+

操作系统课程项目 OS project —— Pintos from Project 1 to Project 3

Pintos Project 陪伴我们操作系统课程大半个学期了…… 虽然做了这么长时间,个人能力有限,pintos代码,看过的可能也就看懂了一半吧,更不用说没看过的了…… 但是也找到了一些有价值的资料,整理一下,供后辈们参考…… 关于环境的问题,最好是用ubuntu 16.04 windows用户不要折腾装双系统了,特别是win10,动不动更新一下,说不定双系统就出问题了,linux...

Deserted Land 8556

Bean的作用域中prototype原型模式(浅拷贝和深拷贝)

在Spring中Bean有五个作用域,其中singleton和prototype分别是单例模式和原型模式。 这里讲一下单例模式和原型模式,进行整理方便我复习。 spring中bean的创建实际就是两种:单例模式和原型模式。(原型模式需要和工厂模式搭配起来) 一、原型模式 原型模式是23种设计模式的其中一种。  在创建对象时通过new关键字创建的对象 (类加载判断,内存分配,初始化等),在我们需要大...

qq_37432174的博客 2186

Classic AUTOSAR精讲专栏目录

欢迎大家来到钢琴上的汽车软件创建的《Classic AUTOSAR精讲系列专栏》,期待在这里能够与大家一起进步,分享成功,分享喜悦!下面蓝色的文章标题都是传送门,点击直接跳转到对应文章。

酒无忧的博客 3913

设计模式:原型模式介绍 && 原型模式的深拷贝问题

0、背景 克隆羊问题:有一个羊,是一个类,有对应的属性,要求创建完全一样的10只羊出来。 那么实现起来很简单,我们先写出羊的类: public class Sheep { private String name; private int age; private String color; //下面写上对应的get和set方法,以及对应的构造器 } 然后,创建10只一样的羊,就在客户端写一个代码创建: //原始羊 Sheep sheep = new Sheep("tom

LifeGoesOn 508

SAP_PP模块跑完 MRP,MD04 里却看不到“计划订单”?排查这 3 个最容易被忽略的主数据参数

MRP 是 SAP 逻辑最严密的模块之一,它绝不会随机罢工。当 MD04 里看不到计划订单时,请不要怀疑系统的计算能力。99% 的情况,都是因为我们给系统下达了矛盾的指令:一边告诉它“我有需求”,一边却通过主数据告诉它“不要计划”、“不要触发”或者“我是冻结的”。掌握这 3 个排查点,你就能在 5 分钟内解决大部分“MRP 失灵”的悬案,成为用户眼中的“系统神医”。

我小时候很黑的博客 599

数据分析案例-汽车客户信息数据可视化分析

本数据集来源于kaggle,原始数据集共有8068条,11个特征变量,各变量含义解释如下:ID:客户IDGender:客户性别Ever_Married:客户婚姻状况Age:客户年龄Graduated:客户是毕业生吗?Profession:客户的职业Work_Experience:多年工作经验Spending_Score:客户的消费评分Family_Size:客户家庭成员人数(含客户)Var_1:客户的匿名类别Segmentation:(目标)客户的客户群。

m0_64336780的博客 1万+

原型模式(深拷贝和浅拷贝)

原型模式概念 原型模式,其实就是拷贝对象的意思,如何拷贝一个对象? 最普通的方式就是再new一个,然后将需要被拷贝对象的所有属性一个一个复制到新对象中。这种方式显然效率极低,如果对象的属性特别多呢?一个个写不疯掉了? 因此,Java中提供了原型模式,就是用来拷贝对象使用的。 源码中的案例 在Spring框架中,创建bean的时候,有个标签,让你选择是: Prototype Singleton 其中Singleton指的是单例模式 而Prototype就是原型模式的意思,意思是,Spring容器中这个对象是按

weixin_43923436的博客 987

基于摩尔线程 S80 显卡在 Ubuntu 系统下双卡交火部署 DeepSeek

curl -X POST -H "Content-Type: application/json" -d '{"prompt": "你的问题"}' http://localhost:11434/api/generate。curl -X POST -H "Content-Type: application/json" -d '{"prompt": "你的问题"}' http://localhost:11434/api/generate。- 为避免模型占用系统盘空间,可将模型存储路径修改到其他磁盘。

靡不有初,鲜克有终 1198

Spring注解开发

Spring注解开发 开发工具与关键技术: eclipse Java 作者: 撰写时间:2021年9月28 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 首先是依赖包,Spring注解开发依赖的依赖包。 在Spring4之后要使用注解开发必须保证aop的包导入了 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200928202550439.png?x-oss-proces...

weixin_44540196的博客 206

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Spring的Bean原型模式下的使用

摘要:本文探讨了Spring中原型(Prototype)模式Bean的使用问题与解决方案。问题原因包括@Autowired注入只初始化一次、代理模式问题及不当获取方式。提供了四种解决方案:通过ApplicationContext获取、使用ObjectProvider、Lookup方法和Provider接口。分析了原型模式的适用场景:有状态Bean、线程不安全对象、需要新实例及避免副作用的场景。最后指出使用注意事项,包括内存管理、性能影响、依赖管理和测试复杂性,强调需权衡资源开销与功能需求。

weixin_50055999的博客 1745

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

JAVA设计模式——【原型模式】

原型模式 克隆羊问题 现在有一只羊 tom,姓名为: tom,年龄为:1,颜色为:白色,请编写程序创建和 tom羊属性完全相同的10只羊。 传统方式解决克隆羊问题 思路分析(图解) 代码演示: public class Sheep { private String name; private int age; private String color; public Sheep(String name, int age, String color) { super(); .

龍弟-idea的博客 7956

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

设计模式 原型模式 与 Spring 原型模式源码解析(包含Bean的创建过程)

原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象。原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的细节。工作原理是:通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建,即对象.clone。

李虹柏的博客 2141

原型模式、克隆与对象拷贝全解析 —— Spring Bean原型模式与Java Object.clone实战精髓

在软件开发中,随着系统复杂度提升,对象创建逐渐成为性能与架构的瓶颈。传统new方式难以满足高效、灵活的对象生产需求。**原型模式(Prototype Pattern)**由GoF设计模式提出,强调“以现有对象为原型,通过复制快速生成新实例”。Java自1.0起即支持对象克隆(),而Spring框架自2.x版本引入了Bean的原型作用域(),将对象拷贝思想与IoC容器管理深度结合,推动了企业级应用的进步。原型模式属于创建型设计模式不依赖类构造器,而是通过原型对象的克隆方法生成新实例。复杂对象初始化耗时。

IT技术学习与工作笔记分享 1353

原型模式在JDK以及Spring源码中如何进行串联

1、原型模式

蒙奇D灬小武的博客 583

java设计模式之原型模式

java设计模式之原型模式

m0_47944994的博客 4222

C++设计模式:原型模式

在本案例中,如果对史莱姆的原型进行克隆,也就是分裂成不同的对象,而不同的史莱姆型号会对应着不同的技能,假设大型史莱姆是撞击,普通史莱姆是喷射,小型史莱姆是自爆,则简单地进行深克隆以及浅克隆可能会引起异常。因此,对此的解决办法便是原型模式结合状态模式使用,状态模式是指在软件构建过程中,某些对象的状态如果发生改变,其行为也会随之发生变化,使用状态模式将能允许一个对象在其内部状态发生改变时改变它的行为,从而使对象看起来似乎修改了其行为。,普通史莱姆转换成小型史莱姆,其中四只转换后的小型史莱姆共享血量(

ajbb093的博客 1549

设计模式第8讲——原型模式(Prototype)

原型模式属于创建型设计模式。 一、什么是原型模式 二、角色组成 三、优缺点 四、应用场景 4.1 生活场景 4.2 java场景 五、代码实现5.0 UML类图5.1 HeroSkill(英雄--具体原型类)5.2 StealManFactory(塞拉斯--客户端)5.3 TestPrototype六、总结

让~学习~成为一种习惯(橡 皮 人の技术博客) 4941

【设计模式】--原型模式

克隆羊问题 现在有一只羊tom,姓名为: tom, 年龄为:1,颜色为:白色,请编写程序创建和tom羊 属性完全相同的4只羊。 传统方式 public class Sheep { private String name; private int age; private String color; public Sheep(String name, int age, String color) { super(); this.name =

fu-jw的博客 5433

设计模式——原型模式

本文主要介绍软件设计模式中的原型模式,通过具体案例来引出原型模型是什么,创建原型模型的好处,以及如何创建原型模型,同时引出浅拷贝和深拷贝的区别,介绍在什么情况下进行浅拷贝和深拷贝。

weixin_73659282的博客 1307

Spring5设计模式 - 原型模式

设计模式 - 原型模式 --------目录直通车-------设计模式 - 原型模式一、浅克隆二、深克隆三、克隆破坏单例模式 原型模式是指原型实例指定创建对象的种类,并复制这些原型这些原型创建新的对象。 主要适用于: (1)大量的Getter和Setter 赋值的场景 (2)类初始化消耗资源较多。 (3)使用 new 生成一个对象需要非常繁琐的过程(数据准备、访问权限)。 (4)构造函数比较复杂。 (5)在循环体中产生大量对象。 ​ 在 Spring 中,原型模式应用得非常广泛,例如 scope=“pr

DJun的博客 1302
上一篇: spring属性配置执行过程,单列和原型区别
下一篇: spring中BeanFactory和FactoryBean的区别
javaPie
博客等级 码龄16年 1171粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值