背景说明:
外围系统想推送账务类数据到中台系统,账务类数据大多数数据都是相似的,少部分差异。所以想只做一个公用接口,根据来源区分,不同的来源调用存储在表里面静态方法做映射或校验。下面是网上找到的一个DEMO。测试时OK的。朋友后面推荐Spring Boot org.springframework.util.ReflectionUtils 实现更方便。此文档记录仅作参考,如果错误或改进意见请各位指正。
测试reflect函数
import java.lang.reflect.*;
public class MyTestClass{
private static Object pLock = new Object();
private static MyTestClass p_instance = null;
private String s_configName = "";
private boolean b_isFromResource = true;
public static Object getInstance(String sConfigName,
Boolean bIsFromResource){
synchronized(pLock){
if(null == p_instance){
p_instance =
new MyTestClass(sConfigName,bIsFromResource);
}
System.out.println("sConfigName = " + sConfigName);
System.out.println("bIsFromResource = " + bIsFromResource);
}
return p_instance;
}
private MyTestClass(String sConfigName,Boolean bIsFromResource){
s_configName = sConfigName;
b_isFromResource = bIsFromResource.booleanValue();
}
public void echoInfo(){
System.out.println("current arguments : configName=["+
s_configName+"],isFromResource=["+
b_isFromResource+"]");
}
public static void main(String[] args) throws Exception{
// 设置方法的传入参数的类型.
Class[] parameterTypes = new Class[]{
java.lang.String.class,
java.lang.Boolean.class
};
Method mGetInstance = null;
String className = "com.netease.dms.MyTestClass";
Class curTestClass = Class.forName(className);
try{
mGetInstance = curTestClass.
getMethod("getInstance",parameterTypes);
}
catch(NoSuchMethodException e){
e.printStackTrace();
mGetInstance = null;
}
if(mGetInstance != null){
Object[] parameter = new Object[2];
parameter[0] = "src/myconfig.properties";
parameter[1] = Boolean.FALSE;
MyTestClass pObj = (MyTestClass)
mGetInstance.invoke(
null,
parameter
);
pObj.echoInfo();
}
else{
throw
new Exception("myTest Init Failed from class" +
className +
System.getProperty("line.seperator","/n") +
"method getInstance(String, Boolean) exists.");
}
}
测试Spring boot, ReflectionUtils方法
准备一个对象
import com.fasterxml.jackson.annotation.JsonFormat;
import com.netease.core.common.exception.SysException;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.util.Date;
@Data
public class ReflectionUtilsTestDo {
public String sourceCode;
private String batchId = "1234567890";
@JsonFormat(pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
public Date trxDate;
private BigDecimal finPeriod;
public String testMethod(String str, Date date) {
System.out.println("执行:testMethod");
return "methodTest1 str = " + str + " date = " + date;
}
public String exceptionMethod(String str) {
throw new SysException("test exception method: " + str);
}
}
测试方法
import lombok.SneakyThrows;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
/**
* @author yachao.wu@corp.netease.com
* @date 2022-05-12
*/
public class ReflectionUtilsTestDemo {
@SneakyThrows
public static void main(String[] args) {
ReflectionUtilsTestDo testDo = new ReflectionUtilsTestDo();
testDo.setSourceCode("AMS");
System.out.println("sourceCode = " + testDo.getSourceCode());
// 获取对象
Field fieldSource = ReflectionUtils.findField(ReflectionUtilsTestDo.class, "sourceCode");
System.out.println("对象sourceCode = " + fieldSource);
System.out.println("对象sourceCode名称 = " + fieldSource.getName());
System.out.println("对象sourceCode类型 = " + fieldSource.getType());
System.out.println("对象sourceCode值(只有public对象才可以获取值) = " + ReflectionUtils.getField(fieldSource, testDo));
// 设置对象值
ReflectionUtils.setField(fieldSource, testDo, "EBS");
System.out.println("对象值sourceCode-设置后 = " + ReflectionUtils.getField(fieldSource, testDo));
// 获取日期类型对象值
Field fieldTrxDate = ReflectionUtils.findField(ReflectionUtilsTestDo.class, "trxDate");
System.out.println("对象TrxDate值 = " + ReflectionUtils.getField(fieldTrxDate, testDo));
ReflectionUtils.setField(fieldTrxDate, testDo, new Date());
System.out.println("对象TrxDate值-设置后 = " + ReflectionUtils.getField(fieldTrxDate, testDo));
// 获取注解方法
Method method = ReflectionUtils.findMethod(ReflectionUtilsTestDo.class, "getSourceCode");
System.out.println("getSourceCode() = " + ReflectionUtils.invokeMethod(method, testDo));
// 获取带参数的方法
Class[] testMethodClasses = new Class[2];
testMethodClasses[0] = String.class;
testMethodClasses[1] = Date.class;
Method testMethod = ReflectionUtils.findMethod(ReflectionUtilsTestDo.class, "testMethod", testMethodClasses);
if (testMethod == null) {
throw new AssertionError("未获取到方法:testMethod");
}
Object[] testParameter = new Object[2];
testParameter[0] = "测试带参数的方法";
testParameter[1] = new Date();
System.out.println("testMethod() = " + ReflectionUtils.invokeMethod(testMethod, testDo, testParameter));
// 执行带例外的方法
Class[] exceptionMethodClasses = new Class[1];
exceptionMethodClasses[0] = String.class;
Method exceptionMethod = ReflectionUtils.findMethod(ReflectionUtilsTestDo.class, "exceptionMethod", exceptionMethodClasses);
if (exceptionMethod == null) {
throw new AssertionError("未获取到方法:exceptionMethod");
}
Object[] exceptionParameter = new Object[1];
exceptionParameter[0] = "测试异常方法";
try {
ReflectionUtils.invokeMethod(exceptionMethod, testDo, exceptionParameter);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
控制台日志
sourceCode = AMS
对象sourceCode = public java.lang.String com.netease.dms.ReflectionUtilsTestDo.sourceCode
对象sourceCode名称 = sourceCode
对象sourceCode类型 = class java.lang.String
对象sourceCode值(只有public对象才可以获取值) = AMS
对象值sourceCode-设置后 = EBS
对象TrxDate值 = null
对象TrxDate值-设置后 = Fri Dec 23 11:52:38 CST 2022
getSourceCode() = EBS
执行:testMethod
testMethod() = methodTest1 str = 测试带参数的方法 date = Fri Dec 23 11:52:38 CST 2022
test exception method: 测试异常方法
Process finished with exit code 0