利用反照写自动装配类或转换器

利用反射写自动装配类或转换器
工作的时候,时常会遇到需要对一些类重新装配的问题,例如,由于Java传递对象本质上是传引用,直接利用对象类型的参数,可能会修改该参数;但是实际工作中,我们往往不想修参数,但是又希望利用该参数,那怎么办呢?
只好重新拷贝一个对象。
如果该类有几十个字段(实际往往是这样),我们装配对象就太费体力了,而且冗长的装配代码可能也不是我们想要的。那怎么办呢??
(1)对于通用情况的处理
由于类中的字段都是私有的,而访问控制一般借助于相应的get和set方法。那好吧,我们就可以利用反射,遍历所有set方法,然后调用源对象的get方法。ok,通用情况搞定。
(2)如果有例外的字段呢,有些字段并没有get或set方法,有has...或isOpen,之类的方法,直接调用源对象的get方法显然不行。对于这些例外字段,有些需要,有些实际上拷贝的时候可以不要。因此,我们可以实际2个list存放这些字段:
specialFieldNameList 和 needProcessFieldsList ,前者存放所有特殊的字段,后面那个列表存放以上特殊字段中需要进行处理的字段。
ok,明确了需求,可以动工了,代码如下:
public class BaseConverter  {
	 private final Logger logger = LoggerFactory.getLogger(this.getClass());
	/**
	 * 特殊字段列表,只针对有set方法的属性字段
	 */
	private List<String> specialFieldNameList = new ArrayList<String>();
	/**
	 * 上述特殊字段列表(specialFieldNameList)中需要进行处理的字段列表
	 */
	private List<String> needProcessFieldsList = new ArrayList<String>();
	/**
	 * 是否是例外方法
	 * @param methodName
	 * @return
	 */
	public BaseConverter(){}
	public BaseConverter(List<String> specialFieldNameList,
			List<String> needProcessFieldsList) {
		super();
		this.specialFieldNameList = specialFieldNameList;
		this.needProcessFieldsList = needProcessFieldsList;
	}
	public boolean isSpecialMethod(String methodName) {
		List<String> specialFieldNameList = this.getSpecialFieldNameList();
		String targetField = methodName.substring(3, 4).toLowerCase()
				+ methodName.substring(4);
		if (specialFieldNameList.contains(targetField))
			return true;
		else
			return false;
	}
	/**
	 * 处理该特殊方法的返回值
	 * @param methodName
	 * @return
	 */
	public boolean needProcess(String methodName) {
		List<String> needProcessFieldsList = this.getNeedProcessFieldsList();
		String targetField = methodName.substring(3, 4).toLowerCase()
				+ methodName.substring(4);
		if (needProcessFieldsList.contains(targetField))
			return true;
		else
			return false;
	}
	

	public  Object processSpecialMethod(Method targetMethod, Object srcObject,
			Object targetObject){
		String targetMethodName = targetMethod.getName();
	//此处省略	。。。。
				targetMethod.invoke(targetObject, value);
			} catch (Exception e) {
//				e.printStackTrace();
				logger.error("[Error:processSpecialMethod....encount an error]",e.getMessage());
			} 
		}
		return targetObject;
	}
	/**
	 * 
	 * @param targetMethod
	 * @param srcObject
	 * @param targetObject
	 * @return
	 * @throws Exception
	 */
	public Object processTargetMethod(Method targetMethod, Object srcObject,
			Object targetObject) throws Exception {
		String targetMethodName = targetMethod.getName();
//		logger.info("[Info:processTargetMethod]:"+ targetMethodName);
		if (targetMethodName.substring(0, 3).contains("set")) {
			// 先处理一般属性的字段
			if (!isSpecialMethod(targetMethodName)) {
				// 先处理一般属性的字段
				Method srcMethod = srcObject.getClass().getMethod(
						("g" + targetMethodName.substring(1)));
				Object value = srcMethod.invoke(srcObject);
				targetMethod.invoke(targetObject, value);
			} else if (needProcess(targetMethodName)) {
				targetObject = this.processSpecialMethod(targetMethod,
						srcObject, targetObject);
			}
		}
		return targetObject;
	}
	/**
	 * DO对象转换
	 * @param srcObject
	 * @param targetObject
	 * @return
	 * @throws Exception
	 */
	public Object convertToObject(Object srcObject, Object targetObject) throws Exception {
		if(srcObject == null)
			return null;
		Class<?> targetClass = targetObject.getClass();
		Method[] methods = targetClass.getDeclaredMethods();
		Method targetMethod;
		for (int j = 0; j < methods.length; j++) {
			targetMethod = methods[j];
			targetObject = this.processTargetMethod(targetMethod, srcObject, targetObject);
			targetObject = this.processTargetMethod(targetMethod, srcObject, targetObject);
		}
		Method[] superMethods = null;
		Class<?> superClass;
		while ((superClass = targetClass.getSuperclass()) != null) {
			superMethods = targetClass.getSuperclass().getDeclaredMethods();
			for (int j = 0; j < superMethods.length; j++) {
				targetMethod = superMethods[j];
				targetObject = this.processTargetMethod(targetMethod,
						srcObject, targetObject);
			}
			targetClass = superClass;
		}
		return targetObject;
	}
	
	
	public void setSpecialFieldNameList(List<String> specialFieldNameList) {
		this.specialFieldNameList = specialFieldNameList;
	}

	public List<String> getSpecialFieldNameList() {
		return specialFieldNameList;
	}

	public List<String> getNeedProcessFieldsList() {
		return needProcessFieldsList;
	}

	public void setNeedProcessFieldsList(List<String> needProcessFieldsList)   {
		this.needProcessFieldsList = needProcessFieldsList;
	}
}