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);  
    }  
  
}  

设计模式-原型模式