Optimizing multiple method calls using Java reflection

Posted by nazariah on Thu, 06 Feb 2020 17:11:12 +0100

I haven't been writing a blog for a while, and I've been missing my thoughts. I have time to write a post today.Previous leaders proposed to optimize part of the system module, according to business requirements, there are many products in the system, there are N indicators under the product, one indicator corresponds to a method, so the system code is such a case: a product will write many invoked methods, these methods can also be invoked by other products, abstracted.Then I think of Java reflection, through the reflection mechanism Java execution method, through the database configuration to achieve flexible calls, whether in the future add products or add or delete metrics methods, you can directly configure the database without modifying the Java code, not to mention, go dry.



ClassData.java for configuration
 1 public class ClassData {
 2     
 3     //java Class Name
 4     private String packages;
 5     
 6     //Method Name
 7     private String className;
 8     //Parameter type name required by method
 9     private String parameter1;
10     //Parameter type name required by method
11     private String parameter2;
12     //What name will the value be received by this method, for example User Class name attribute    This value is 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     }

Simulated data I write directly here for convenience, preferably by building tables to configure in the database to get the corresponding collection list from the database

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 This is the Java class configured above

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:"+ name);
        
        return "Name"+name;
    }
    
    public Integer getAgeVal(String age){
        
        System.out.println("Age:"+ (age));
        
        return 18;
    }
    
    public Date getDateVal(String date){
        
        System.out.println("Time:"+ date);
        
        return new Date();
    }
    
    public BigDecimal getMyVal(String bigg){
        BigDecimal big = new BigDecimal(100);
        System.out.println("Money:"+ big);
        
        return big;
    }
    
}

 

 

Methods for assigning attributes to entity classes

public static <T> T modelTrim(T model,String names,Object invoke){
        Class<T> clazz = (Class<T>) model.getClass();
        //Get All bean All member variables in
        Field[] fields = clazz.getDeclaredFields();
        for(int j=0;j<fields.length;j++){
            if(fields[j].getName().equals(names)){
                //Get All bean Medium variable type is String Variables of
                //if("Integer".equals(fields[j].getType().getSimpleName())){
                    try {
                        if(invoke != null && !"".equals(invoke)){
                            //Obtain set Method Name
                            String setMethodName = "set"+fields[j].getName().substring(0, 1).toUpperCase()
                                    +fields[j].getName().replaceFirst("\\w", "");
                            //obtain get Methodological Method object,With parameters
                            Method setMethod = clazz.getDeclaredMethod(setMethodName,fields[j].getType());
                            setMethod.setAccessible(true);
                            //assignment
                            setMethod.invoke(model, (Object)(invoke));
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                //}
            }
        }
        System.out.println("model--"+model.toString());
        return model;
}

 

Execute main method

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("Pre-Execution"+user.toString()+"invoke:"+invoke);
                modelTrim(user,cd.getNames(),invoke);
                
                System.out.println("After execution"+user.toString()+"\n");
                
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

 

 

 

Get results

 

 

 

This is done through Java reflection, is it fairly flexible and will provide convenience in the future.

Topics: Java Database Attribute