![设计模式就该这样学:基于经典框架源码和真实业务场景](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=1739297985-LmAsaS0Hma6oR7He2mauUMFlfP3UfFFd-0-6f8ef769d3e4ee2966ef80524be4d2b9)
定义接口还是很简单的,我们找源码其实只需要看哪些接口实现了Cloneable即可。来看ArrayList类的实现。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt011_20.jpg?sign=1739297985-DOT8Vt0nN9vxsiUogTREEtWc8jUM9TGD-0-745df283646d094d1f9aaf62ff826401)
我们发现,clone()方法只是将List中的元素循环遍历了一遍。此时,再思考一下,是不是这种形式就是深克隆呢?其实用代码验证一下就知道了,继续修改ConcretePrototype类,增加一个deepCloneHobbies()方法。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt011_21.jpg?sign=1739297985-Pe78tiTnOkMtK7DEdoOZJRpfFzHcJ1A8-0-129e34372221b38633784be6c3c3a378)
客户端代码修改如下。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt011_22.jpg?sign=1739297985-0OpjfmzUdnTVj6KX4T0DKppQd7q7Ue3y-0-1726febd0a4491234b03ad32bd09cac9)
运行代码也能得到期望的结果。但是这样的代码其实是硬编码。如果在对象中声明了各种集合类型,则每种情况都需要单独处理。因此,深克隆的写法一般会直接用序列化来操作。
9.3.2 原型模式在Spring源码中的应用
在Spring中,如果用户将创建对象的方式设置为原型,则每次调用getBean()的时候都要重新创建一个新的对象返回。和单例模式一样,还是继续来看doGetBean()方法的代码片段。
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt011_23.jpg?sign=1739297985-kGmBgcVPVuNxWB7djxPnkPqlxlszvUVW-0-d57ebe4991f81dd5a1369d81ac87a1cf)
![img](https://epubservercos.yuewen.com/A1F36C/17725769807799506/epubprivate/OEBPS/Images/txt011_24.jpg?sign=1739297985-rqRnJpD36Q16MlJhIpzXeF3yxQE6gojD-0-e73c5c31aca58cbeb6932887f1efcf1d)
Spring中创建对象的方式默认采用单例模式,可以通过设置@Scope(“prototype”)注解将其改为原型模式。但是,采用单例模式创建或者采用原型模式创建,只能二选一。