# Java实战系列 - APT生成代码

2021/7/27 22:07:19

本文主要是介绍# Java实战系列 - APT生成代码,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

本文主要介绍如何使用APT在编译期生成class文件

准备

  • 开始之前,需要引入jar包,一个是谷歌的工具包,帮助我们自动生成META-INF目录下的配置,另一个是生成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引入)

使用

  • 新建一个工程引入上面的jar,查看引入的jar在 META-INF.services 下面有一个 javax.annotation.processing.Processor 配置文件,里面是 com.lushwe.HelloAnnotationProcessor ,这个就是上面引入谷歌jar包 auto-service 自动生成的,不然的需要我们手工创建,虽然都可以,但是麻烦,这样比较方便,详细如图
    在这里插入图片描述

  • 创建一个配置类,代码注解 @Hello ,否则无法处理注解处理器

@Hello
public class HelloConfig {
}
  • 然后编译即可触发注解处理器,然后就会在target目标自动生成代码
  • class代码如下,其中get set方法是 @Getter @Setter 帮我们创建的
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;
    }
}
  • java代码如下:
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;
}
  • 截图证明
    在这里插入图片描述

本文完。



这篇关于# Java实战系列 - APT生成代码的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程