这是我第一次编写Annotation Processor,我想以编程方式调用它.可能吗?
我为处理器编写了小代码:
@SupportedAnnotationTypes({"app.dev.ems.support.annotation.HBMModel"})
public class HBMModelProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(HBMModel.class);
System.out.println(elements);
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
现在如果我想调用流程方法,那我该怎么做呢?我可以通过以下方式完成:
HBMModelProcessor modelProcessor = new HBMModelProcessor();
modelProcessor.process(annotations, roundEnv)
Run Code Online (Sandbox Code Playgroud)
任何信息对我都非常有帮助.
谢谢.
我正在实现一个注释处理器,以确保标记有注释的元素是实现某个接口的类的实例,或者是实现某个接口的类型的使用:
@Documented
@Target(value = { ElementType.PARAMETER, ElementType.TYPE_USE })
@Retention(value = RetentionPolicy.RUNTIME)
public @interface AuditSubject {
}
public interface Auditable {
// methods that provide data for writing a log entry...
}
public class Report implements Auditable {
}
Run Code Online (Sandbox Code Playgroud)
对于带注释的元素,必须在方法执行后(使用AOP)创建日志条目.例子:
@CreateLogEntry
public Result persist(@AuditSubject Report newReport) {
// A log entry must be created based on the incoming 'newReport' instance.
}
@CreateLogEntry
public UpdateResult<@AuditSubject Report> update(Report update) {
// A log entry must be created based on the updated report, which …Run Code Online (Sandbox Code Playgroud) java annotations annotation-processing java-8 annotation-processor
我使用google/auto-value在 maven 项目中创建不可变的值类。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
[...]
<packaging>war</packaging>
<properties>
<auto-value.version>1.7</auto-value.version>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId>
<version>${auto-value.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.auto.value</groupId>
<artifactId>auto-value-annotations</artifactId>
<version>${auto-value.version}</version>
</dependency>
[...]
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Run Code Online (Sandbox Code Playgroud)
这就像使用 CLI(例如mvn clean test)的魅力一样,但在 IntelliJ 项目构建期间会产生错误:
Error:java: java.lang.NoClassDefFoundError: com/google/auto/service/AutoService
com.google.auto.service.AutoService
Run Code Online (Sandbox Code Playgroud)
值得注意的是:正确的源代码生成到generated-sources/annotations/...但在这一步之后 IntelliJ 构建失败并且不会创建生成的测试源目录generated-test-sources/...。
虽然可以通过将另一个注释处理器路径添加到 maven-compiler-plugin
<path>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
<version>1.0-rc6</version>
</path>
Run Code Online (Sandbox Code Playgroud)
此修复程序的缺点是auto-service在 …
我刚刚进入这里的javax AnnotationProcessing,并遇到了一个丑陋的案例.我将在一系列描述我学习过程的伪代码行中进行说明:
MyAnnotation ann = elementIfound.getAnnotation(MyAnnotation.class);
// Class<?> clazz = ann.getCustomClass(); // Can throw MirroredTypeException!
// Classes within the compilation unit don't exist in this form at compile time!
// Search web and find this alternative...
// Inspect all AnnotationMirrors
for (AnnotationMirror mirror : element.getAnnotationMirrors()) {
if (mirror.getAnnotationType().toString().equals(annotationType.getName())) {
// Inspect all methods on the Annotation class
for (Entry<? extends ExecutableElement,? extends AnnotationValue> entry : mirror.getElementValues().entrySet()) {
if (entry.getKey().getSimpleName().toString().equals(paramName)) {
return (TypeMirror) entry.getValue();
}
}
return null;
}
}
return …Run Code Online (Sandbox Code Playgroud) 我写了一个注释处理器。用户可以传递一个选项作为处理器的参数。我也可以在我的注释处理器中读取这个参数。到目前为止一切顺利,一切都按预期进行!
但是,我从编译器收到警告,传递给注释处理器的选项尚未被任何注释处理器识别:
警告:以下选项未被任何处理器识别:'[fragmentArgsLib]'
实际上,我的处理器已成功识别并读取此选项:
@Override public boolean process(Set<? extends TypeElement> type, RoundEnvironment env) {
String fragementArgsLib = processingEnv.getOptions().get("fragmentArgsLib");
...
}
Run Code Online (Sandbox Code Playgroud)
我想我必须手动说我已经使用这个选项来使这个编译器警告消失。你们中有人知道怎么做吗?
我编写了一个AnnotationProcessor扫描代码中某个注释并从中生成 Java 类的程序。它基本上做了这样的事情:
private Multimap<String, Element> elements;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(Factory.class)) {
elements.put(annotatedElement.getSimpleName());
}
generateCode(elements);
}
Run Code Online (Sandbox Code Playgroud)
以防万一:
generateCode()将迭代elements,这是一个多重映射,并为每个键创建一个类(键+后缀是我想要生成的文件的名称),并使用根据元素列表的信息创建的代码(与 key 关联的某个 key 的 multimap 的值。
显然我会调用generateCode()每一轮注释处理。因此,我会收到一个编译错误,表明在上一轮中已经生成了同名的文件。
处理这个问题的正确方法是什么?我认为收集所有注释并仅在最后一轮生成类是个好主意,如下所示:
private Multimap<String, Element> elements;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (Element annotatedElement : roundEnv.getElementsAnnotatedWith(Factory.class)) {
elements.put(annotatedElement.getSimpleName());
}
if (roundEnv.processingOver()){
generateCode(elements);
}
}
Run Code Online (Sandbox Code Playgroud)
这解决了多次生成相同文件的问题,但现在我收到以下警告:
警告:java:上一轮创建的类型为[生成的java文件的路径]的文件将不会受到注释处理。
javadoc 指出您不应该在上一轮中生成代码。我应该什么时候生成我的文件?
此外,如果我单击重建项目,我还会在 IntelliJ 14 中收到此警告:警告:输出路径 [生成的 …
我的库中有几个包含注释和基类的包。我在这个问题的上下文中扩展了 javax.annotation.processing.AbstractProcessor 。
有没有办法获取包中声明的所有类型的 java.lang.TypeElement 的列表/数组/集合?甚至元素?
目前,我有一个解决方法,通过使用类型上的注释将类标记为组,该类型仅存在于表示库中的相关对象组。是否有更简单的方法按包(即位置)而不是显式声明将类型分组在一起?
我们如何提供带有 Java 11 模块的注释处理器?
要注册注释提供程序,我们需要以下模块信息条目:
import javax.annotation.processing.Processor;
import com.mycompany.mylib.impl.MyAnnotationProcessor;
module com.mycompany.mylib {
provides Processor with MyAnnotationProcessor;
}
Run Code Online (Sandbox Code Playgroud)
现在,不幸的是,这是不是因为包装不够javax.annotation.processing,javax.lang.model.*而javax.tools不是在java.base模块,但在java.compiler模块。
在 Java SE 8 中,一切都只在 JRE 中可用,但在 Java 11 中,我们可以选择只使用一个子集。随着jlink我们再可以创建更小的运行时间图像。
现在,当然,我可以将以下内容添加到模块信息中:
requires java.compiler;
Run Code Online (Sandbox Code Playgroud)
但这也会导致java.compiler成为自定义运行时映像的一部分。
但是注解处理有些特殊:它是在编译时运行的代码,而不是在运行时运行。因此它不应该是运行时映像的一部分。它应该只是编译时要求/依赖项。
有没有办法用 Java 11 模块系统解决这个问题?
我有以下数据类注释@MyAnnotation:
@MyAnnotation
data class MyDataClass(
val foo: Boolean = true,
val bar: Int = 123,
val buz: String? = "abc",
)
Run Code Online (Sandbox Code Playgroud)
从ClassDeclaration我可以获取所有KSPropertyDeclaration,并且我能够获取simpleName并解析KSType,但我不知道如何获取每个属性的默认值。
我已将我的构建迁移到使用版本目录。我已从 build.gradle 中删除了以下内容
plugins {
id 'kotlin-android'
id 'kotlin-kapt'
}
Run Code Online (Sandbox Code Playgroud)
和
kapt "androidx.room:room-compiler:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"
Run Code Online (Sandbox Code Playgroud)
现在我得到了
warning: The following options were not recognized by any processor:
'[dagger.hilt.internal.useAggregatingRootProcessor, room.schemaLocation,
dagger.fastInit, dagger.hilt.android.internal.disableAndroidSuperclassValidation,
dagger.hilt.android.internal.projectType]'
Run Code Online (Sandbox Code Playgroud)
1 条警告
和
A failure occurred while executing
com.android.build.gradle.internal.tasks.MergeJavaResWorkAction
> 2 files found with path 'META-INF/gradle/incremental.annotation.processors' from
inputs:
- /.gradle/caches/transforms-
3/5f588ae3973231906376832b3350f55d/transformed/jetified-hilt-android-compiler-
2.45.jar
- /.gradle/caches/transforms-
3/f1c91d9e7fbd546100043f736678c477/transformed/jetified-dagger-compiler-2.45.jar
Run Code Online (Sandbox Code Playgroud)
现在我想知道如何kotlin-kapt作为插件添加到版本目录中。或者如何使用annotationProcessor版本目录?
annotation-processing android-studio android-gradle-plugin android-jetpack-compose
java ×7
annotations ×2
auto-value ×1
java-8 ×1
javac ×1
kotlin ×1
maven ×1
module-info ×1
reflection ×1