前言:
反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
下面介绍俩个在实际运用中反射的应用:
场景一:DTO的数据封装
在大多数软件架构中有一层DTO层,用于提供于与前端的数据交互。示意如下图:
数据传输对象(DTO)(Data Transfer Object),是一种设计模式之间传输数据的软件应用系统。数据传输目标往往是数据访问对象从数据库中检索数据。数据传输对象与数据交互对象或数据访问对象之间的差异是一个以不具有任何行为除了存储和检索的数据(访问和存取器)。
例如,我们要给APP端提供用户信息,将要用到的数据封装到UserModel,然后利用反射,提交给前端。
/**
* 获取用户资料
*
* @param userId
* @return
*/
@RequestMapping(value=Router.User.GET_USER_BASIC_INFORMATION,method=RequestMethod.POST)
@ResponseBody
public Response get_user_basic_information(@RequestParam("userId") int userId) {
log.info("infoMsg:--- 获取用户资料开始");
Response reponse = this.getReponse();
UserModel model = new UserModel();
try {
UserEntity user = appUserService.findById(userId);
if(user != null) {
mergeEneity(user, model);
}
log.info("infoMsg:--- 获取用户资料结束");
return reponse.success(model);
} catch (Exception e) {
log.error("errorMsg:{--- 获取用户资料失败:" + e.getMessage() + "---}");
return reponse.failure(e.getMessage());
}
}
/**
* 合并俩个对象,并验证get、set方法是否一致
* @param targetBean
* @param sourceBean
* @return
*/
public static Object mergeEneity(Object targetBean, Object sourceBean){
if(targetBean == null || sourceBean == null){
return targetBean;
}
Method[] sourceBeanMethods = sourceBean.getClass().getMethods();
Method[] targetBeanMethods = targetBean.getClass().getMethods();
for(Method m : sourceBeanMethods){
if(m.getName().indexOf("get") > -1){
String set = m.getName().replaceFirst("g", "s");
for(Method t : targetBeanMethods){
if(set.equals(t.getName())){
try {
Object res = m.invoke(sourceBean);
if(null != res){
t.invoke(targetBean, res);
}
break;
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
return targetBean;
}
场景二:因为业务原因在修改个人资料的时候,只修改资料中随机一个字段的信息,所以为了简化抽象,利用了反射。
/**
* 编辑用户资料
*
* @param userId
* @param fieldName
* @param fieldValue
* @return
*/
@RequestMapping(value=Router.User.EDIT_USER_INFORMATION,method=RequestMethod.POST)
@ResponseBody
public Response edit_user_information(@RequestParam("userId") int userId,
@RequestParam("fieldName") String fieldName,@RequestParam("fieldValue") String fieldValue) {
log.info("infoMsg:--- 用户修改资料开始");
Response reponse = this.getReponse();
try {
PageData pd = new PageData<>();
pd.put("userId", userId);
pd.put("fieldName", fieldName);
pd.put("fieldValue", fieldValue);
appUserService.edit_user_information(pd);
log.info("infoMsg:--- 用户修改资料结束");
return reponse.failure();
} catch (Exception e) {
log.error("errorMsg:{---用户修改资料失败:" + e.getMessage() + "---}");
return reponse.failure(e.getMessage());
}
}
/**
* 编辑用户资料
*
* @param pd
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public void edit_user_information(PageData pd) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
int userId = (int) pd.get("userId");
UserEntity user = appUserDao.findById(userId);
String fieldName = pd.getString("fieldName");
String fieldValue = pd.getString("fieldValue");
Method[] methods = user.getClass().getMethods();
Field[] fields = user.getClass().getFields();
for(Field fidle : fields) {
if(fieldName.equals(fidle.getName())) {
for(Method m : methods) {
if(m.getName().equalsIgnoreCase("set" + fieldName)) {
// m.invoke(fieldName, fieldValue);
m.invoke(fieldValue, user);
appUserDao.edit_user_information(pd);
}
}
}
}
}