相信作Java的童鞋或多或少都听过反射,这也应该是Java从入门到进阶的必经之路。java
可是在咱们的实际开发中直接使用它们的概率貌似仍是比较少的,(除了造轮子或者是Spring Mybatis这些框架外
)。git
因此这里介绍一个在实际开发中仍是小有用处的反射实例。github
有关反射的一些基本知识就不说了,能够自行Google
,也能够看下反射入门。数据库
日志相信你们都不陌生,在实际开发中一些比较敏感的数据表咱们须要对它的每一次操做都记录下来。缓存
先来看看传统的写法:框架
@Test
public void insertSelective() throws Exception {
Content content = new Content() ;
content.setContent("asdsf");
content.setCreatedate("2016-12-09");
contentService.insertSelective(content) ;
ContentLog log = new ContentLog();
log.setContentid(content.getContentid());
log.setContent("asdsf");
log.setCreatedate("2016-12-09");
contentLogService.insertSelective(log);
}复制代码
很是简单,就是在保存完数据表以后再把相同的数据保存到日志表中。工具
可是这样有如下几个问题:spa
setter()
方法就得写几百次,还得是都写对的状况下。针对以上的状况就得须要反射这个主角来解决了。日志
咱们先来先来看下使用反射以后对代码所带来的改变:code
@Test
public void insertSelective2() throws Exception {
Content content = new Content();
content.setContent("你好");
content.setContentname("1");
content.setCreatedate("2016-09-23");
contentService.insertSelective(content);
ContentLog log = new ContentLog();
CommonUtil.setLogValueModelToModel(content, log);
contentLogService.insertSelective(log);
}复制代码
一样的保存日志,无论多少字段,只须要三行代码便可解决。
并且就算以后字段发生改变写日志这段代码仍然不须要改动。
其实这里最主要的一个方法就是CommonUtil.setLogValueModelToModel(content, log);
来看下是如何实现的;
/** * 生成日志实体工具 * * @param objectFrom * @param objectTo */
public static void setLogValueModelToModel(Object objectFrom, Object objectTo) {
Class<? extends Object> clazzFrom = objectFrom.getClass();
Class<? extends Object> clazzTo = objectTo.getClass();
for (Method toSetMethod : clazzTo.getMethods()) {
String mName = toSetMethod.getName();
if (mName.startsWith("set")) {
//字段名
String field = mName.substring(3);
//获取from 值
Object value;
try {
if ("LogId".equals(field)) {
continue;
}
Method fromGetMethod = clazzFrom.getMethod("get" + field);
value = fromGetMethod.invoke(objectFrom);
//设置值
toSetMethod.invoke(objectTo, value);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}复制代码
再使用以前咱们首先须要构建好主的数据表,而后new
一个日志表的对象。
在setLogValueModelToModel()
方法中:
getMethod()
方法返回数据表中的该字段的getter
方法。String content = content.getContent();
setter
方法为日志对象的每个字段赋值。log.setContent("asdsf");
其中字段名称为LogId
时跳出了当前循环,由于LogId是日志表的主键,是不须要赋值的。
当循环结束时,日志对象也就构建完成了。以后只须要保存到数据库中便可。
反射实际上是很是耗资源的,再使用过程当中仍是要慎用。
其中对method、field、constructor等对象作缓存也是颇有必要的。
我的博客地址:crossoverjie.top。
GitHub地址:github.com/crossoverJi…。