本文主要介绍如何使用APT在编译期生成class文件
<dependency> <groupId>com.google.auto.service</groupId> <artifactId>auto-service</artifactId> <version>1.0-rc2</version> </dependency> <dependency> <groupId>com.squareup</groupId> <artifactId>javapoet</artifactId> <version>1.13.0</version> </dependency>
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface Hello { }
import com.google.auto.service.AutoService; import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.TypeSpec; import lombok.Getter; import lombok.Setter; import lombok.SneakyThrows; import javax.annotation.processing.*; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic; import java.util.Set; @AutoService(Processor.class) @SupportedAnnotationTypes("com.lushwe.Hello") @SupportedSourceVersion(value = SourceVersion.RELEASE_8) public class HelloAnnotationProcessor extends AbstractProcessor { private Elements elementUtils; private Types typeUtils; private Filer filer; private Messager messager; @Override public synchronized void init(ProcessingEnvironment processingEnvironment) { super.init(processingEnvironment); elementUtils = processingEnvironment.getElementUtils(); typeUtils = processingEnvironment.getTypeUtils(); messager = processingEnvironment.getMessager(); filer = processingEnvironment.getFiler(); } @Override @SneakyThrows public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) { if (set.isEmpty()) { return false; } Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(Hello.class); for (Element element : elements) { parseElement(element); } return true; } private void parseElement(Element element) throws Exception { String packageName = elementUtils.getPackageOf(element).getQualifiedName().toString(); String className = element.getSimpleName().toString(); messager.printMessage(Diagnostic.Kind.NOTE, "=HelloProcessor=" + packageName + "/" + className); FieldSpec id = FieldSpec.builder(Long.class, "id") .addModifiers(Modifier.PRIVATE) .addJavadoc("ID") .build(); FieldSpec name = FieldSpec.builder(String.class, "name") .addModifiers(Modifier.PRIVATE) .addJavadoc("名称") .build(); TypeSpec typeSpec = TypeSpec.classBuilder("HelloWorld") .addModifiers(Modifier.PUBLIC) .addAnnotation(Getter.class) .addAnnotation(Setter.class) .addField(id) .addField(name) .build(); JavaFile javaFile = JavaFile.builder(packageName, typeSpec) .build(); // 写入 javaFile.writeTo(filer); } }
新建一个工程引入上面的jar,查看引入的jar在 META-INF.services
下面有一个 javax.annotation.processing.Processor
配置文件,里面是 com.lushwe.HelloAnnotationProcessor
,这个就是上面引入谷歌jar包 auto-service
自动生成的,不然的需要我们手工创建,虽然都可以,但是麻烦,这样比较方便,详细如图
创建一个配置类,代码注解 @Hello
,否则无法处理注解处理器
@Hello public class HelloConfig { }
package com.lushwe; public class HelloWorld { private Long id; private String name; public HelloWorld() { } public Long getId() { return this.id; } public String getName() { return this.name; } public void setId(Long id) { this.id = id; } public void setName(String name) { this.name = name; } }
package com.lushwe; import java.lang.Long; import java.lang.String; import lombok.Getter; import lombok.Setter; @Getter @Setter public class HelloWorld { /** * ID */ private Long id; /** * 名称 */ private String name; }
本文完。