相信作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…。