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

使用Java反射优化多个方法调用的更多相关文章

  1. Java 反射 Method的invoke回调调用任意方法

    Java 反射 Method的invoke回调调用任意方法 @author ixenos 关键子:Method.Field.invoke方法指针/函数指针.回调函数 invoke回调流程示例 0.由C ...

  2. Atitit.通过null 参数 反射  动态反推方法调用

    Atitit.通过null 参数 反射  动态反推方法调用 此时,直接使用java  apache的ref工具都失效了.必须要自己实现了. 如果调用接口方法的话,就不能使用apache的ref工具,可 ...

  3. java反射构建对象和方法的反射调用

    Java反射技术应用广泛,其能够配置:类的全限定名,方法和参数,完成对象的初始化,设置是反射某些方法.可以增强java的可配置性. 1.1 通过反射构建对象(无参数): 例如我们使用 ReflectS ...

  4. java反射之获取所有方法及其注解(包括实现的接口上的注解),获取各种标识符备忘

    java反射之获取类或接口上的所有方法及其注解(包括实现的接口上的注解) /** * 获取类或接口上的所有方法及方法上的注解(包括方法实现上的注解以及接口上的注解),最完整的工具类,没有现成的工具类 ...

  5. 深入理解java虚拟机(十一) 方法调用-解析调用与分派调用

    方法调用过程是指确定被调用方法的版本(即调用哪一个方法),并不包括方法执行过程.我们知道,Class 文件的编译过程中并不包括传统编译中的连接步骤,一切方法调用在 Class 文件调用里面存储的都只是 ...

  6. Java APi 之 RMI远程方法调用

    一.什么是RPC RPC全称是remote procedure call,即远程过程调用.它是一种协议,用于从远程计算机上请求服务. 例如有两台服务器A和B,A上的应用想要调用B上应用的方法,但是他们 ...

  7. Java反射机制的使用方法

    Java的反射机制同意你在程序执行的过程中获取类定义的细节.有时候在程序执行的时候才得知要调用哪个方法,这时候反射机制就派上用场了. 获取类 类的获取方法有下面几种: forName().通过Clas ...

  8. java反射与多态(父类调用子类)的代码演示

    package Test0817; import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method ...

  9. JAVA反射优化

    ****************** 转自 https://my.oschina.net/19921228/blog/3042643 *********************** 比较反射与正常实例 ...

随机推荐

  1. Jquery.ajax dataType参数

    dataType 类型:String 预期服务器返回的数据类型.如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断,比如 XML MIME 类型就被识别为 XML.在 1.4 ...

  2. visual studio git for coding

    直接放图吧 双击存储库项目进入Git操作页面 点击之后输入你要发布的git地址 选择你的操作 如果你登录的密码错了 就需要去修改 否则永远都pull失败 打开控制面板 在这里修改

  3. C++ 断言

    assert宏 (基本概念与用法整理) assert宏的深入学习 1.运行时断言 1.1.assert属于运行时断言,可以在运行时判断给定条件是否为真,如果为真则什么也不做,否则打印一跳错误信息,然后 ...

  4. Linux系统打开文件最大数量限制(进程打开的最大文件句柄数设置)

    ulimit  [-HSTabcdefilmnpqrstuvx  [limit]] 利用ulimit命令可以对资源的可用性进行控制. -H选项和-S选项分别表示对给定资源的硬限制(hard limit ...

  5. C++版 - UVa1585 Score - 题解

    C++版 - UVa1585 Score - 题解 <算法竞赛入门经典(第二版)> 习题3-1 得分(ACM/ICPC Seoul 2005,UVa1585) 问题描述: 给出一个由O和X ...

  6. 使用Spring Cloud搭建服务注册中心

    我们在之前的博客中已经介绍过阿里的分布式服务框架dubbo[Linux上安装Zookeeper以及一些注意事项][一个简单的案例带你入门Dubbo分布式框架],但是小伙伴们应该也看到了,阿里的dubb ...

  7. 爬虫入门(三)——动态网页爬取:爬取pexel上的图片

    Pexel上有大量精美的图片,没事总想看看有什么好看的自己保存到电脑里可能会很有用 但是一个一个保存当然太麻烦了 所以不如我们写个爬虫吧(๑•̀ㅂ•́)و✧ 一开始学习爬虫的时候希望爬取pexel上的 ...

  8. Perl处理和收走子进程(退出状态码和wait)

    本文关于处理子进程退出状态码的内容主体来自于<Pro Perl>的第21章. 子进程退出状态码 每个子进程在退出时,操作系统都会保留它们的退出状态码,并在内核维护的进程表中保留子进程项.对 ...

  9. 解决java web中safari浏览器下载后文件中文乱码问题

    解决java web中safari浏览器下载后文件中文乱码问题 String fileName = "测试文件.doc"; String userAgent = request.g ...

  10. 高效开发者是如何个性化VS Code插件与配置的?

    2年之前,我放弃了Sublime Text,选择了Visual Studio Code作为代码编辑器. 我每天花在VS Code上的时间长达5~6个小时,因此按照我的需求优化VS Code配置十分必要 ...