1、引入java字节码操作库
1、引入java字节码操作库
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.27.0-GA</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
2、示例demo
- 创建空类
package com.sourcecode.helloworld.dto;
public class ExcelDto {
}
- 对空类进行添加属性
package com.sourcecode.helloworld.dynamic;
import javassist.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashSet;
import java.util.Set;
@RestController
public class TestController {
private static Set<String> existSet = new HashSet<>();
private static boolean exist = false;
private static Class clazz;
@GetMapping("/test")
public void test(String property){
Object obj = addFields(property.split(","));
System.out.println(obj);
}
private Object addFields(String ...fields){
int addCount = 0;
try {
//默认的类搜索路径
ClassPool pool = ClassPool.getDefault();
//获取一个ctClass对象
CtClass ctClass = pool.getCtClass("com.sourcecode.helloworld.dto.ExcelDto");
if(exist){
ctClass.defrost();
}
for (String field : fields) {
if(existSet.contains(field)){
continue;
}
//添加属性
ctClass.addField(CtField.make(String.format("private String %s;", field), ctClass));
//添加set方法
ctClass.addMethod(CtMethod.make(String.format("public void set%s(String %s){this.%s = %s;}", captureName(field), field, field, field), ctClass));
//添加get方法
ctClass.addMethod(CtMethod.make(String.format("public int get%s(){return this.%s;}", captureName(field), field), ctClass));
}
for (String field : fields) {
if(!existSet.contains(field)){
existSet.add(field);
addCount++;
}
}
if(!exist){
clazz = ctClass.toClass();
exist = true;
} else {
if(addCount>0){
Loader classLoader = new Loader(pool);
clazz = classLoader.loadClass("com.sourcecode.helloworld.dto.ExcelDto");
}
}
return clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将字符串的首字母转大写
* @param str 需要转换的字符串
* @return
*/
private static String captureName(String str) {
// 进行字母的ascii编码前移,效率要高于截取字符串进行转换的操作
char[] cs=str.toCharArray();
cs[0]-=32;
return String.valueOf(cs);
}
}
3、访问:http://localhost:8080/test?property=unionId,hospitalId,name,age
可以看到类已经添加了4个属性
可以看到类已经添加了各自的set、get方法