依赖
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.4.13</version>
</dependency>
两个元类
import lombok.AllArgsConstructor;
import lombok.Data;
/**
* 用来描述注解信息
*/
@Data
@AllArgsConstructor
public class AnnotationDto {
/**
* 导包地址,例:import cn.hutool.core.bean.BeanUtil;
*/
private String packageInfo;
/**
* 注解名称,例:@PostMapping(value = "/getUserRoles")
*/
private String name;
}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 用来描述字段信息
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ColumnDto {
/**
* 字段名称
*/
private String propertyName;
/**
* 字段类型String/Date/Integer...
*/
private String propertyType;
/**
* 字段上注解
*/
private List<AnnotationDto> annotations;
}
工具类:
package com.ciih.workshop.utils.clazz;
import cn.hutool.core.util.StrUtil;
import groovy.lang.GroovyClassLoader;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
* 运行时生成实体类-工具类
*
* @author sunziwen
*/
@Slf4j
public class RunTimeClassUtil {
/**
* 生成运行时实体类
*
* @param className 实体类名称
* @param packagePath 包名路径
* @param annotationDtos 类上注解
* @param columnDtos 字段信息
* @return
*/
@SneakyThrows
public static Class<?> createClass(String className, String packagePath, List<AnnotationDto> annotationDtos, List<ColumnDto> columnDtos) {
//字段
String property = "private {propertyType} {propertyName};\n";
//字段set
String propertySet =
"public void set{PropertyName}({propertyType} {propertyName}) {\n" +
"this.{propertyName} = {propertyName};\n" +
"}\n";
//字段get
String propertyGet =
"public {propertyType} get{PropertyName}() {\n" +
"return this.{propertyName};\n" +
"}\n";
ArrayList<String> list = new ArrayList<>();
if (columnDtos != null) {
for (ColumnDto columnDto : columnDtos) {
HashMap<String, String> map = new HashMap<>();
map.put("propertyName", columnDto.getPropertyName());
map.put("propertyType", columnDto.getPropertyType());
//首字母大写
map.put("PropertyName", StrUtil.upperFirst(columnDto.getPropertyName()));
//添加注解
if (columnDto.getAnnotations() != null) {
List<String> collect = columnDto.getAnnotations().stream().map(AnnotationDto::getName).collect(Collectors.toList());
list.addAll(collect);
}
//添加字段
list.add(StrUtil.format(property, map));
//添加字段set方法
list.add(StrUtil.format(propertySet, map));
//添加字段get方法
list.add(StrUtil.format(propertyGet, map));
}
}
//groovy提供了一种将字符串文本代码直接转换成Java Class对象的功能
GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
//里面的文本是Java代码,但是我们可以看到这是一个字符串我们可以直接生成对应的Class<?>对象,而不需要我们写一个.java文件
StringBuilder classString = new StringBuilder();
//包名
classString.append(packagePath).append(";\n");
//导入依赖包
if (annotationDtos != null) {
for (AnnotationDto annotationDto : annotationDtos) {
classString.append(annotationDto.getPackageInfo()).append(";\n");
}
}
//导入依赖包
if (columnDtos != null) {
for (ColumnDto columnDto : columnDtos) {
List<AnnotationDto> annotations = columnDto.getAnnotations();
if (annotations != null && annotations.size() > 0) {
for (AnnotationDto annotation : annotations) {
classString.append(annotation.getPackageInfo()).append(";\n");
}
}
}
}
//导入类上注解
if (annotationDtos != null) {
for (AnnotationDto annotationDto : annotationDtos) {
classString.append(annotationDto.getName()).append("\n");
}
}
classString.append("\n").append("public class ").append(StrUtil.upperFirst(StrUtil.toCamelCase(className))).append(" {\n");
//导入字段
classString.append(StrUtil.join("\n", list)).append("}\n");
System.out.println(classString.toString());
Class<?> clazz = groovyClassLoader.parseClass(classString.toString());
return clazz;
}
}
使用示例:
public static void main(String[] args) {
//类上注解
ArrayList<AnnotationDto> annotationDtos = new ArrayList<>();
annotationDtos.add(new AnnotationDto("import com.baomidou.mybatisplus.annotation.TableName", "@TableName(value = \"u_permission\")"));
//字段
ArrayList<ColumnDto> columnDtos = new ArrayList<>();
ColumnDto columnDto = new ColumnDto();
columnDto.setPropertyName("username");
columnDto.setPropertyType("String");
ArrayList<AnnotationDto> arrayList = new ArrayList<>();
arrayList.add(new AnnotationDto("import io.swagger.annotations.ApiModelProperty", "@ApiModelProperty(value = \"" + UUID.randomUUID() + "\")"));
columnDto.setAnnotations(arrayList);
columnDtos.add(columnDto);
Class<?> user = RunTimeClassUtil.createClass("User", "package com.ciih.workshop.utils.clazz", annotationDtos, columnDtos);
}