Java注解处理器、语法树修剪
2020/8/6大约 2 分钟
Java注解处理器、语法树修剪
依赖
- auto-service 方便生成Processor
 - qdox 解析java文件
 - tools.jar javac工具,修改语法树,也支持遍历javadoc
 
maven使用tools.jar
<profiles>
        <profile>
            <id>default-tools.jar</id>
            <activation>
                <property>
                    <name>java.vendor</name>
                    <value>Sun Microsystems Inc.</value>
                </property>
            </activation>
            <dependencies>
                <dependency>
                    <groupId>com.sun</groupId>
                    <artifactId>tools</artifactId>
                    <version>1.8</version>
                    <scope>system</scope>
                    <systemPath>${java.home}/../lib/tools.jar</systemPath>
                </dependency>
            </dependencies>
        </profile>
    </profiles>autoservice
        <dependency>
            <groupId>com.google.auto.service</groupId>
            <artifactId>auto-service</artifactId>
            <version>1.0-rc7</version>
        </dependency>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>com.google.auto.service</groupId>
                            <artifactId>auto-service</artifactId>
                            <version>1.0-rc7</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>编译器
种类
- Javac
 - eclipse(ecj)
 - Groovy-Eclipse
 - Ajc
 
Java Annotation Processor
javax.annotation.processing.Processor接口有一个实现抽象类AbstractProcessor,默认实现了以下方法,提供注解实现
- Set getSupportedOptions() -- @SupportedOptions
 - Set getSupportedAnnotationTypes(); -- @SupportedAnnotationTypes
 - SourceVersion getSupportedSourceVersion(); -- @SupportedSourceVersion
 
注:注解配置降低了代码的复杂度
例子
// 生成配置文件META-INF/services/xxxx
@AutoService(Processor.class)
// 所有注解(必须要声明)
@SupportedAnnotationTypes("*")
// 版本
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class DemoProcessor extends AbstractProcessor {
    
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        // 如果返回true,不会流到下面的处理器
        return false;
    }
}使用Spi
在注解处理器中使用spi,依赖也需要像注解处理器一样的方式引入,不然加载不到
获取JCCompilationUnit
JCCompilationUnit代表一个完整Class
	private JCCompilationUnit toUnit(Element element) {
		TreePath path = null;
		if (trees != null) {
			try {
				path = trees.getPath(element);
			} catch (NullPointerException ignore) {
				// Happens if a package-info.java dowsn't conatin a package declaration.
				// https://github.com/rzwitserloot/lombok/issues/2184
				// We can safely ignore those, since they do not need any processing
			}
		}
		if (path == null) return null;
		
		return (JCCompilationUnit) path.getCompilationUnit();
	}element转tree
com.sun.source.util.Trees
trees = Trees.instance(javacProcessingEnv);
// 获取Tree
tress.getTree(element)Tree获取element
Tree中的sym变量就是element对象
