使用Java反射優化多個方法調用


  有段時間沒來寫博客了,心里一直念叨空了來,今天有時間來記錄一篇。前段時間領導提出優化部分系統模塊,根據業務要求系統中有很多產品,產品下面有N個指標,一個指標就對應一個方法,所以系統代碼中就是這樣一個情況:一個產品下面會寫很多調用的方法,這些方法其他產品也可以調用的,抽象出來的。然后我就想到了Java反射,通過反射機制java執行方法,通過數據庫配置達到靈活調用,不管以后增加產品還是增刪指標方法,都可以不用修改Java代碼直接數據庫配置就行了,話不多說,上干貨。



ClassData.java 用於配置
 1 public class ClassData {
 2     
 3     //java類名稱
 4     private String packages;
 5     
 6     //方法名
 7     private String className;
 8     //方法需要的參數類型名
 9     private String parameter1;
10     //方法需要的參數類型名
11     private String parameter2;
12     //這個方法得出的值用什么名字接收  比如 User類的name屬性    這個值就是name
13     private String names;
14     
15     
16 
17     public String getNames() {
18         return names;
19     }
20 
21     public void setNames(String names) {
22         this.names = names;
23     }
24 
25     public String getPackages() {
26         return packages;
27     }
28 
29     public void setPackages(String packages) {
30         this.packages = packages;
31     }
32 
33     public String getClassName() {
34         return className;
35     }
36 
37     public void setClassName(String className) {
38         this.className = className;
39     }
40 
41     public String getParameter1() {
42         return parameter1;
43     }
44 
45     public void setParameter1(String parameter1) {
46         this.parameter1 = parameter1;
47     }
48 
49     public String getParameter2() {
50         return parameter2;
51     }
52 
53     public void setParameter2(String parameter2) {
54         this.parameter2 = parameter2;
55     }

模擬數據 這里我是直接寫的為了方便  最好是建表配置在數據庫 從數據庫得到相應的集合list

public static List<ClassData> getlist(){
        List<ClassData> list = new ArrayList<ClassData>();
        ClassData c = new ClassData();

  

          c.setPackages("com.cq.test.clas.ClassVo");
      c.setClassName("getNameVal");
      c.setParameter1("java.lang.String");
      c.setNames("name");
      ClassData c1 = new ClassData();
      c1.setPackages("com.cq.test.clas.ClassVo");
      c1.setClassName("getAgeVal");
      c1.setParameter1("java.lang.String");
      c1.setParameter2("java.lang.String");
      c1.setNames("age");
      ClassData c2 = new ClassData();
      c2.setPackages("com.cq.test.clas.ClassVo");
      c2.setClassName("getDateVal");
      c2.setParameter1("java.lang.String");
      c2.setNames("date");
      ClassData c3 = new ClassData();
      c3.setPackages("com.cq.test.clas.ClassVo");
      c3.setClassName("getMyVal");
      c3.setParameter1("java.lang.String");
      c3.setNames("my");

      list.add(c);

 list.add(c1); list.add(c2); list.add(c3); return list; }

    

 

  user.java

package com.cq.test.vo;

import java.math.BigDecimal;
import java.util.Date;

public class User {
    
    private String name;
    
    private Integer age;
    
    private Date date;
    
    private BigDecimal my;

    

    public String getName() {
        return name;
    }



    public void setName(String name) {
        this.name = name;
    }



    public Integer getAge() {
        return age;
    }



    public void setAge(Integer age) {
        this.age = age;
    }



    public Date getDate() {
        return date;
    }



    public void setDate(Date date) {
        this.date = date;
    }



    public BigDecimal getMy() {
        return my;
    }



    public void setMy(BigDecimal my) {
        this.my = my;
    }



    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + ", date=" + date
                + ", my=" + my + "]";
    }
    
    

    
    

}

 

ClassVo.java 這是上面配置的java類

package com.cq.test.clas;

import java.math.BigDecimal;
import java.util.Date;

public class ClassVo {
    
    public String getNameVal(String name){
        
        System.out.println("名字:"+ name);
        
        return "名字"+name;
    }
    
    public Integer getAgeVal(String age){
        
        System.out.println("年齡:"+ (age));
        
        return 18;
    }
    
    public Date getDateVal(String date){
        
        System.out.println("時間:"+ date);
        
        return new Date();
    }
    
    public BigDecimal getMyVal(String bigg){
        BigDecimal big = new BigDecimal(100);
        System.out.println("錢:"+ big);
        
        return big;
    }
    
}

 

 

 給實體類屬性賦值的方法

public static <T> T modelTrim(T model,String names,Object invoke){
        Class<T> clazz = (Class<T>) model.getClass();
        //獲取所有的bean中所有的成員變量
        Field[] fields = clazz.getDeclaredFields();
        for(int j=0;j<fields.length;j++){
            if(fields[j].getName().equals(names)){
                //獲取所有的bean中變量類型為String的變量
                //if("Integer".equals(fields[j].getType().getSimpleName())){
                    try {
                        if(invoke != null && !"".equals(invoke)){
                            //獲取set方法名
                            String setMethodName = "set"+fields[j].getName().substring(0, 1).toUpperCase()
                                    +fields[j].getName().replaceFirst("\\w", "");
                            //得到get方法的Method對象,帶參數
                            Method setMethod = clazz.getDeclaredMethod(setMethodName,fields[j].getType());
                            setMethod.setAccessible(true);
                            //賦值
                            setMethod.invoke(model, (Object)(invoke));
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                //}
            }
        }
        System.out.println("model--"+model.toString());
        return model;
}

 

 執行main方法

public class MethodTest {
    public static void main(String[] args){
        
        List<ClassData> getlist = getlist();
        int i = 1;
        User user = new User();
        
        System.out.println(user.getName());
        for(ClassData cd:getlist){
            try {
                Class<?> userClass = Class.forName(cd.getPackages());
                Object object = userClass.newInstance();
                Method refTest1 = userClass.getDeclaredMethod(cd.getClassName(),Class.forName(cd.getParameter1()));
                Object invoke = refTest1.invoke(object, "1");
                i++;
                System.out.println("執行前"+user.toString()+"invoke:"+invoke);
                modelTrim(user,cd.getNames(),invoke);
                
                System.out.println("執行后"+user.toString()+"\n");
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

 

 

 

得到結果

 

 

 

至此通過Java反射執行方法就完成了,是不是相當靈活,對以后提供了便捷。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM