prototype模式
场景,如果一个对象,我们希望拷贝一个这个对象,就是弄出来这个类的另外一个实例,实例的属性跟之前的实例是一模一样的
我们要用原型模式,以某一个对象为原型,然后对这个对象进行拷贝,得到拷贝后的另外一个对象
直接就copy一份就可以了,但是这里要记住深拷贝和浅拷贝的区别
其实一般实现原型模式的时候,直接是通过覆盖Object类的clone()方法即可,在里面实现自己的拷贝逻辑就可以了
工程应用场景:在BO VO DTO 之间拷贝数据的时候
可以覆盖clone方法,然后封装一个深拷贝的工具类.
深拷贝有2种方式实现:
1、反射
2、cglib动态代理
我们采用2 动态代理的方式性能比反射好100倍。
import java.util.HashMap;
import java.util.Map;
import net.sf.cglib.beans.BeanCopier;
/**
* BeanCopier工具类
* @author weimiantong
*
*/
public class BeanCopierUtils {
/**
* BeanCopier缓存
*/
public static Map<String, BeanCopier> beanCopierCacheMap = new HashMap<String, BeanCopier>();
/**
* 将source对象的属性拷贝到target对象中去
* @param source source对象
* @param target target对象
*/
public static void copyProperties(Object source, Object target){
String cacheKey = source.getClass().toString() +
target.getClass().toString();
BeanCopier beanCopier = null;
if (!beanCopierCacheMap.containsKey(cacheKey)) {
synchronized(BeanCopierUtils.class) {
if (!beanCopierCacheMap.containsKey(cacheKey)) {
beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
beanCopierCacheMap.put(cacheKey, beanCopier);
}
}
} else {
beanCopier = beanCopierCacheMap.get(cacheKey);
}
beanCopier.copy(source, target, null);
}
}
以上实现,在没有并发的时候是ok,但是多线程会有线程安全的问题,改进如下:
/**
* BeanCopier工具类
* @author
*
*/
public class BeanCopierUtils {
/**
* BeanCopier缓存
*/
public static Map<String, BeanCopier> beanCopierCacheMap = new HashMap<String, BeanCopier>();
/**
* 将source对象的属性拷贝到target对象中去
* @param source source对象
* @param target target对象
*/
public static void copyProperties(Object source, Object target){
String cacheKey = source.getClass().toString() +
target.getClass().toString();
BeanCopier beanCopier = null;
// 线程1和线程2,同时过来了
if (!beanCopierCacheMap.containsKey(cacheKey)) {
// 两个线程都卡这儿了
// 但是此时线程1先获取到了锁,线程2就等着
synchronized(BeanCopierUtils.class) {
// 线程1进来之后,发现这里还是没有那个BeanCopier实例
// 此时线程2,会发现缓存map中已经有了那个BeanCopier实例了,此时就不会进入if判断内的代码
if(!beanCopierCacheMap.containsKey(cacheKey)) {
// 进入到这里会创建一个BeanCopier实例并且放在缓存map中
beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
beanCopierCacheMap.put(cacheKey, beanCopier);
} else {
beanCopier = beanCopierCacheMap.get(cacheKey);
}
}
} else {
beanCopier = beanCopierCacheMap.get(cacheKey);
}
beanCopier.copy(source, target, null);
}
}
- 本文链接: https://blog.zoozer.club/archives/-she-ji-mo-shi-gong-cheng-shi-jian--yuan-xing-mo-shi
- 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!