【发布时间】:2021-10-19 06:42:23
【问题描述】:
对于一个项目,我正在试验 javassist(java 二进制代码操作库)。
我能够使用以下代码创建一个简单的 POJO 类
public static Class<?> createClass(ModelClass clazz) throws NotFoundException, CannotCompileException {
ModelProperty[] properties = clazz.getProperties();
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.makeClass(clazz.getName());
// add annotation
ClassFile classFile = ctClass.getClassFile();
ConstPool constpool = classFile.getConstPool();
AnnotationsAttribute annotationsAttribute = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
System.out.println(Data.class.getName());
Annotation annotation = new Annotation(lombok.Data.class.getName(), constpool);
Annotation annotation1 = new Annotation(Component.class.getName(), constpool);
Annotation annotation2 = new Annotation(Deprecated.class.getName(), constpool);
annotationsAttribute.setAnnotations(new Annotation[] {annotation, annotation1, annotation2});
ctClass.getClassFile().addAttribute(annotationsAttribute);
for (ModelProperty property : properties) {
String camelCaseField = property.getName().substring(0, 1).toUpperCase() + property.getName().substring(1);
CtField ctField = new CtField(resolveCtClass(property.getType()), property.getName(), ctClass);
ctClass.addField(ctField);
// add getter
// CtMethod fieldGetter = CtNewMethod.getter("get" + camelCaseField, ctField);
// ctClass.addMethod(fieldGetter);
// add setter
// CtMethod fieldSetter = CtNewMethod.setter("set" + camelCaseField, ctField);
// ctClass.addMethod(fieldSetter);
}
return ctClass.toClass();
}
// ModelClass
@Data
public class ModelClass {
private String name;
private ModelProperty[] properties;
public void setName(String name) {
this.name = name;
}
public void setModelProperty(ModelProperty[] properties) {
this.properties = properties;
}
}
// ModelProperty
@Data
public class ModelProperty {
private String name;
private Class<?> type;
public void setType(String type) {
switch (type.toLowerCase()) {
case "int":
case "integer":
this.type = Integer.class;
break;
case "float":
this.type = Float.class;
break;
case "str":
case "string":
this.type = String.class;
break;
case "bool":
case "boolean":
this.type = Boolean.class;
break;
default:
this.type = String.class;
break;
}
}
}
我可以使用 createClass 方法创建类。在使用反射 API 检查类时,我注意到 lombok.Data 注释未添加到类中。
Class<?> clazz = PojoCreator.createClass(modelClassPerson);
for (final Method method : clazz.getMethods()) {
System.out.println(method);
}
for (final Annotation annotation : clazz.getAnnotations()) {
System.out.println(annotation);
}
for (final Method method : clazz.getDeclaredMethods()) {
System.out.println(method);
}
for (final Annotation annotation : clazz.getDeclaredAnnotations()) {
System.out.println(annotation);
}
输出
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
@org.springframework.stereotype.Component(value="")
@java.lang.Deprecated(forRemoval=false, since="")
@org.springframework.stereotype.Component(value="")
@java.lang.Deprecated(forRemoval=false, since="")
从输出中可以看出,spring.Component 和 javalang.Deprecated 已添加,但 lombok.Data 未添加。 p>
pom.xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!-- <scope>annotationProcessor</scope> -->
</dependency>
尝试将范围设置为 compile、runtime、provided,但似乎都不起作用。
使用mvn spring-boot:run在命令行中执行
我哪里做错了?
谢谢。
【问题讨论】:
标签: java spring reflection lombok javassist