使用Java反射优化多个方法调用

  有段时间没来写博客了,心里一直念叨空了来,今天有时间来记录一篇。前段时间领导提出优化部分系统模块,根据业务要求系统中有很多产品,产品下面有N个指标,一个指标就对应一个方法,所以系统代码中就是这样一个情况:一个产品下面会写很多调用的方法,这些方法其他产品也可以调用的,抽象出来的。然后我就想到了Java反射,通过反射机制java执行方法,通过数据库配置达到灵活调用,不管以后增加产品还是增删指标方法,都可以不用修改Java代码直接数据库配置就行了,话不多说,上干货。



ClassData.java  用于配置
 public class ClassData {
     
     //java类名称
     private String packages;
     
     //方法名
     private String className;
     //方法需要的参数类型名
     private String parameter1;
     //方法需要的参数类型名
     private String parameter2;
     //这个方法得出的值用什么名字接收  比如 User类的name属性    这个值就是name
     private String names;
     
     
 
     public String getNames() {
         return names;
     }
 
     public void setNames(String names) {
         this.names = names;
     }
 
     public String getPackages() {
         return packages;
     }
 
     public void setPackages(String packages) {
         this.packages = packages;
     }
 
     public String getClassName() {
         return className;
     }
 
     public void setClassName(String className) {
         this.className = className;
     }
 
     public String getParameter1() {
         return parameter1;
     }
 
     public void setParameter1(String parameter1) {
         this.parameter1 = parameter1;
     }
 
     public String getParameter2() {
         return parameter2;
     }
 
     public void setParameter2(String parameter2) {
         this.parameter2 = parameter2;
     }

模拟数据 这里我是直接写的为了方便 最好是建表配置在数据库 从数据库得到相应的集合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);

<em id="__mceDel">        list.add(c1);
        list.add(c2);
        list.add(c3);
        return list;
    }</em>

  

  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 &amp;&amp; !"".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反射执行方法就完成了,是不是相当灵活,对以后提供了便捷。