English 中文(简体)
利用Java Poet制定通知代号
原标题:Generating code for an annotation using Java Poet
The bounty expires in 7 days. Answers to this question are eligible for a +100 reputation bounty. user1692342 wants to draw more attention to this question.

我想制定方法级说明和说明;为之制定代码。 我想避免使用AspectJ,更喜欢编辑时间代码生成器,这样,如果我先去辩论一下该守则的话,我实际上可以看到,J赢得的那方面使我能够看到。

我来到 Java波特,作为这样做的选择。

我想建立一种称为“弹性”的方法说明,抓住特定方法的执行时间。

因此,如果我采取这样的方法:

@Latency
void process();

产生的法典应当:

try {
   long startTime = System.currentTimeMillis();
   this.process();
} finally {
   System.out.println("Total execution time" + System.currentTimeMillis() - startTime);
}

我的意思是:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Latency {
}

The Javapoet Code is:

package org.example;

import com.google.auto.service.AutoService;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import java.io.IOException;
import java.util.Set;

@AutoService(Processor.class)
public class LatencyProcessor extends AbstractProcessor {

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return Set.of(Latency.class.getName());
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        System.out.println("LatencyProcessor is running...");
        for (Element element : roundEnv.getElementsAnnotatedWith(Latency.class)) {
            if (element.getKind().equals(ElementKind.METHOD)) {
                generateLatencyCode((ExecutableElement) element);
            }
        }
        return true;
    }

    private void generateLatencyCode(ExecutableElement methodElement) {
        String methodName = methodElement.getSimpleName().toString();

        CodeBlock codeBlock = CodeBlock.builder()
            .beginControlFlow("try")
            .addStatement("long startTime = System.currentTimeMillis()")
            .addStatement("$N.$N()", "this", methodName)
            .addStatement("long endTime = System.currentTimeMillis()")
            .addStatement("System.out.println("Method $N execution time: " + (endTime - startTime) + " milliseconds")", methodName)
            .nextControlFlow("catch (Exception e)")
            .addStatement("e.printStackTrace()")
            .endControlFlow()
            .build();

        MethodSpec latencyMethod = MethodSpec.methodBuilder(methodName)
            .addModifiers(Modifier.PUBLIC)
            .addAnnotation(Override.class)
            .returns(TypeName.VOID)
            .addCode(codeBlock)
            .build();

        TypeSpec latencyClass = TypeSpec.classBuilder("Latency_" + methodName)
            .addModifiers(Modifier.PUBLIC)
            .addSuperinterface(ClassName.get(methodElement.getEnclosingElement().asType()))
            .addMethod(latencyMethod)
            .build();

        JavaFile javaFile = JavaFile.builder("generated", latencyClass)
            .build();

        try {
            javaFile.writeTo(processingEnv.getFiler());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

我的建设。 梯度档案:

dependencies {
    implementation  com.squareup:javapoet:1.13.0 
    implementation  com.google.auto.service:auto-service:1.1.1 


    annotationProcessor  com.google.auto.service:auto-service:1.1.1 

}

configurations {
    annotationProcessor
}

I don t see any generated code & LatencyProcessor is never invoked. Am I misunderstanding the use of Javapoet or is it just that I have not set it up correctly?

问题回答

问题似乎在于,你在同一个项目中试图使用习惯通知程序人LatencyProcessor。 相反,需要事先在单独项目或分项目中加以建设,然后在包含附有<代码>@>的附加说明方法的项目中使用该焦拉或分项目作为通知程序者。 Latency。 我用一个次级项目对它进行了测试。 简而言之,我从auto-service中删除,并增加了javax.annotation.process.Processor文档,以人工制作。 还须从<条码>/代码>中删除以下线:<条码>.addStatement(”$N()”、“this”、“pName),否则将生成的<条码><> 程序>方法形成<条码>。 由于它称作“<代码>,/code>方法,再次造成一种无限的漏洞。

build.gradle of subproject containing annotation processor:

plugins {
    id  java 
}

repositories {
    mavenCentral()
}

dependencies {
    implementation  com.squareup:javapoet:1.13.0 
}

build.gradle of main project that uses the annotation processor:

plugins {
    id  java 
}

repositories {
    mavenCentral()
}

dependencies {
    // The subproject is named as annotation-processor in this case
    annotationProcessor project( :annotation-processor )
    compileOnly project( :annotation-processor )
}

jar {
    manifest {
        attributes  Main-Class :  io.github.devatherock.app.App 
    }
}

在实施所产生方法时,产出如下:

Method process execution time: 0 milliseconds

您可在github上找到完整的工作守则。





相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...

热门标签