1. 程式人生 > >Java基礎----jdk1.8 反射實驗

Java基礎----jdk1.8 反射實驗

clas 接口 fin 好的 spring insert 結束 getmethod lsi

(寫在最前:還沒入門的搬磚工的一本正經的胡說八道)

引言: 最近做到的項目中,需要給對接方提供一個公共接口,根據對方傳入的XML文件的rootelement分發調用接口,最簡單的使用if-else if 模式,但是看著實在太蠢。

場景一:需要根據關鍵字,進行接口分發

使用if-else模式缺點:

  1. 看著蠢
  2. 不易閱讀(個人觀點)
  3. 不易維護
  4. balabala...不想編了,就是看著不爽

如果只有一兩個方法還好,如果方法多了,額。。。如下,自行體會。

 1 public class TestMethod {
 2 
 3     public Object dispatchMethod(String name, String data) {
4 Object obj = null; 5 6 if ("methodA".equal(name)) { 7 obj = methodA(data); 8 } else if ("methodB".equal(name)) { 9 obj = methodB(data); 10 } else if (...) { 11 ... 12 } 13 return obj; 14 } 15 16 private
Object methodA(String data) { 17 ... 18 } 19 20 private Object methodB(String data) { 21 ... 22 } 23 24 ... 25 }

那麽步入正題,我才用的反射模式,匹配目標方法,我認為可以降低維護和閱讀成本

開發環境:jdk1.8

實現代碼:

  • 定義目標方法枚舉,包含rootelement信息,調用方法說明,目標方法targetName
 1 public enum MethodEnum {
 2 
 3     METHODA("MethodA","調用方法A","methodA"),
4 METHODB("MethodB","調用方法B","methodB"), 5 ; 6 7 @Getter 8 private String code; //rootelement 9 10 @Getter 11 private String message; 12 13 @Getter 14 private String name; //目標方法名 15 16 private MethodEnum (String code,String message,String name) { 17 this.code = code; 18 this.message = message; 19 this.name = name; 20 } 21 22 public static MethodEnum fromCode(String code) { //根據傳入code,篩選目標方法 23 for (DockingFliggyHotelEnum p : DockingFliggyHotelEnum.values()) { 24 if(p.code.equalsIgnoreCase(code)) { 25 return p; 26 } 27 } 28 return null; 29 } 32 }
  • 定義反射方法工具類
 1 /**
 2  *  定義工具類 
 3 **/
 4 public class MethodUtil {
 5 
 6     public static Method getTargetMethod(Class clazz, String methodName) {
 7         Method[] methods = clazz.getDeclaredMethods(); //獲取所有方法,包含private
 8         if (methods != null && methods.length > 0) {
 9             String regEx  = "^" + methodName +"$";//獲取所要查找到的方法名稱要匹配此正則
10             Pattern pattern = Pattern.compile(regEx);
11             for (Method method : methods) {
12                 Matcher matcher = pattern.matcher(method.getName());
13                 boolean rs = matcher.find();
14                 if(rs){
15                     return method;
16                 }
17             }
18         }
19         return null;
20     }
21 
22     public static Object executeTargrtMethod(Class clazz, String methodName, String xmlData) {
23         Object obj = null;
24         try {
25             Method method = getTargetMethod(clazz, methodName);
26             obj = method.invoke(clazz, xmlData);
27         } catch (Exception e) {
28             
29         }
30         return obj;
31     }
32 
33 }
  • 具體分發
 1 public class TestDispatch {
 2 
 3     public Object dispatch(String root, String xml) {
 4         String name = MethodEnum.fromCode(root).name;
 5         Object obj = executeTargrtMethod(this.getClass(), name, xml)
 6         return obj;
 7     }
 8 
 9     private Object methodA(String xml) {
10         Object obj = null;
11         ...
12         return obj;
13     }
14 
15     private Object methodB(String xml) {
16         Object obj = null;
17         ...
18         return obj;
19     }
20 
21     ...
22 }

對於業務代碼結構清晰明了,是不是看著爽多了。

對於類似的場景很多,都可以使用反射機制。

場景二:項目中多處需要大批量插入數據,提取一個公共方法,減少代碼行數,何樂而不為呢?

對了,順便說一下這個批量插入方法,數據庫使用mysql,項目框架springboot,jdk1.8,5000條數據插入一次,耗時0.8s左右。

 1    /**
 2      * @param batchCount 一次批量插入數據量
 3      * @param target 目標方法關鍵字
 4      * @param list 需要插入的大批量數據
 5      * @throws Exception
 6      */
 7     public static void batchInsert(Class clazz, int batchCount, String target, List<?> list) throws Exception{
 8         Method method = getTargetMethod(target);
 9         int batchLastIndex = batchCount - 1;//每批最後一個的下標
10         for(int index = 0; index < list.size()-1;){
11             if(batchLastIndex > list.size()-1){
12                 batchLastIndex = list.size() - 1;
13                 if (method != null) {
14                     method.invoke(clazz,list.subList(index, batchLastIndex));
15                 }
16                 break;//數據插入完畢,退出循環
17             }else{
18                 if (method != null) {
19                     method.invoke(clazz,list.subList(index, batchLastIndex));
20                 }
21                 index = batchLastIndex + 1;//設置下一批下標
22                 batchLastIndex = index + (batchCount - 1);                
23             }                
24         }
25     }

實驗結束,代碼分析下次在寫了。

寫在最後

代碼是偽代碼,可能啥地方寫得不對,歡迎指正

對於以上兩種場景,我目前只能想到這種方法。。。如果你有更好的,歡迎來懟我

Java基礎----jdk1.8 反射實驗