背景:偶尔想了解一下apt,就去网上看了看文章,发现都写的质量不高,其实对于程序员来说,真的不想那么多废话和干扰信息,只希望看到点实际的,而不是忽略很多细节的环境搭建,如果这都忽略了,那谈那么多后续有什么意义呢?所以就想记录一下,其实我也是抄的别人的,但是我怕原文丢了,就自己写写,顺便写下实践中的一些问题。原文我是从这家(AutoService+javaPoet+maven+注解自动生成java代码_java 注解 自动生成代码-CSDN博客)抄来的,可以去看看,写的基本没差。但是里边关于tools.jar这种包引入是多余的,这个你从我的分享中也可以看出来,我把这些没用的部分都去掉了。
由于不习惯废话,我直接上干货,直接看我截图的目录结构,省得我写了:
上图也看到了,两个模块,testa为底座模块,里边一个注解和一个编译器注解处理器,再加一个spi注入注解处理器实现类;testb为应用模块,只有一个类,使用了testa里边的注解,其他任何多余的东西都没有,只做最简demo,以免扰乱视听。
详细看一下testa的注解如下:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.SOURCE)
public @interface Safety {
String value() default "";
}
关于这个注解的注解处理器如下,
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.TypeElement;
import java.util.Set;
@SupportedAnnotationTypes("com.nxj.annos.Safety")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class SafetyProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
System.out.println("进入process方法");
System.out.println("退出process方法");
return false;
}
}
利用spi注入这个注解处理器(第一张截图里怎么操作已经很明显了),算了,还是插一下图吧。这里有用google的@AutoService注解去注入的,但是我试了一下,去掉spi,使用该注解并没有起作用,有懂的可以指教一下到底怎么用的,由于时间有限,没去研究那个了。
testa的pom文件来看一下:
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.example</groupId>
<artifactId>test-processor</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>testa</artifactId>
<build>
<!-- 指定JDK编译版本 -->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-proc:none</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</project>
没错,就这么一点东西,什么其他的都是多余的,但是当前的这些少了也是不太行,除了编码格式这块可以动,其他的也没什么好能动的了,其中-proc:none是灵魂,主要是声明在这个模块内不启用注解处理器,如果启用了,会找不到注解处理器这个类,不信可以自己去试一下,这个模块前边我们也说了,是给别的模块用的,自己用不起来,为什么用不起来自行百度,一搜就有。
接下来看看testb的类:
import com.nxj.annos.Safety;
/**
* @author nxj
*/
@Safety
public class TestTestaMain {
public static void main(String[] args) {
System.out.println("main");
}
}
除了加了注解,啥也没干,说了,最简。
来看看testb的pom文件:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.example</groupId>
<artifactId>test-processor</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>testb</artifactId>
<name>Archetype - testb</name>
<url>http://maven.apache.org</url>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>testa</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
其实就是依赖了testa模块,剩下基本啥也没干。到此就行了,这个demo就做好了。
直接父pom下执行
mvn clean install
就可以看到自己的输出被打印了,如果想要debug这个方法的话,要用mvnDebug命令启动父模块,没错,是父模块!!!如果用这个命令启动子模块testb,只会顺利完成编译,但是不会debug到testa注解处理器的的断点,
接下来用idea的Remote Debug就可以了
这里有个坑,idea构建的时候有缓存,如果你maven配置文件变化过,使用idea自带的组件编译并不是很好用,可能会报错
这时候直接控制台输命令这样去构建就好了,不用纠结。这里有用
这个机制会帮助我们通过注解做很多代码生成的工作,比如lombok框架,这里只出最简demo,有了架子,里边再写什么生成代码的业务那就是顺理成章的了,希望这次分享能给有需要的人一些帮助,如果有什么好的建议,希望不吝赐教