有段时间没来写博客了,心里一直念叨空了来,今天有时间来记录一篇。前段时间领导提出优化部分系统模块,根据业务要求系统中有很多产品,产品下面有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);
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反射执行方法就完成了,是不是相当灵活,对以后提供了便捷。