![设计模式就该这样学:基于经典框架源码和真实业务场景](https://wfqqreader-1252317822.image.myqcloud.com/cover/758/33114758/b_33114758.jpg)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人
9.3 原型模式在框架源码中的应用
9.3.1 原型模式在JDK源码中的应用
首先定义JDK中的Cloneable接口。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt011_19.jpg?sign=1739946566-TLhjLtaoTPtXFKghb0n5CiShrSGjNyQ7-0-49a068110c96cb13df87c4a6a35fa338)
定义接口还是很简单的,我们找源码其实只需要看哪些接口实现了Cloneable即可。来看ArrayList类的实现。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt011_20.jpg?sign=1739946566-hAVaXJGbEqWEm5g1q6lfT5ll1TC8TehJ-0-af14d55ea8c46a9e7f4e98811612a9de)
我们发现,clone()方法只是将List中的元素循环遍历了一遍。此时,再思考一下,是不是这种形式就是深克隆呢?其实用代码验证一下就知道了,继续修改ConcretePrototype类,增加一个deepCloneHobbies()方法。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt011_21.jpg?sign=1739946566-PqVrfiHIUCrkLyZvfbBVgD2kEr4eVWOn-0-576593111bf338401fd8f5210920b6df)
客户端代码修改如下。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt011_22.jpg?sign=1739946566-5jj1gBthEDbWCq8LK1BjBn7u8DBxDL9n-0-2f816b02c406d9eba87ecdfc313b6789)
运行代码也能得到期望的结果。但是这样的代码其实是硬编码。如果在对象中声明了各种集合类型,则每种情况都需要单独处理。因此,深克隆的写法一般会直接用序列化来操作。
9.3.2 原型模式在Spring源码中的应用
在Spring中,如果用户将创建对象的方式设置为原型,则每次调用getBean()的时候都要重新创建一个新的对象返回。和单例模式一样,还是继续来看doGetBean()方法的代码片段。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt011_23.jpg?sign=1739946566-809RJwJkk9NSuLE7UzahUqsvX3kbyHpH-0-883fc4783076855292a47586ae47b1ec)
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt011_24.jpg?sign=1739946566-RkpbWD6ZlakhrLuFZIHJwvc4H8QpO2rh-0-74756b80ef556055dbcf359dccee1e50)
Spring中创建对象的方式默认采用单例模式,可以通过设置@Scope(“prototype”)注解将其改为原型模式。但是,采用单例模式创建或者采用原型模式创建,只能二选一。