gpt4 book ai didi

java - Jeta:如何创建自定义注释处理器

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:48:57 26 4
gpt4 key购买 nike

plenty of features已在 Jeta 上提供,但是如果缺少某些东西怎么办。我可以创建自己的注释并为它们生成元代码吗?

需要一个分步教程如何创建自定义 Jeta处理器。

最佳答案

如何创建自定义处理器,分步教程

第一步:Hello, World项目

对于本教程,让我们创建一个简单的 Gradle一个模块的项目app并且只有一个类SayHelloApp .这个类写Hello, World!到标准输出。

SayHelloApp

对于我们要创建的插图Hello设置 Hello, Jeta! 的注释字符串到带注释的字段。

第二步:common模块

首先,我们需要一个可以在 app 中访问的模块。和 apt (将很快创建)模块。在 common模块我们需要两个类 - Hello注释和 HelloMetacode界面:

common module

第三步:apt模块
apt - 是一个模块,我们将在其中创建代码生成类所需的所有内容。对于本教程,我们需要一个处理器来处理我们的 Hello注解。

apt module

注意这个模块依赖于common模块所以我们使用 Hello注解作为 super 构造函数的参数。通过这样做,我们对 Jeta 说我们需要用给定类型注释的所有元素。该模块还依赖于 jeta-apt为了访问 Jeta类。

第 4 步:处理器

已创建 SayHelloProcessor现在什么都不做。让我们在其中添加一些逻辑。这里的想法是生成设置 Hello, Jeta 的 java 代码。使用 Hello 注释的字段的字符串.

请注意 Jeta使用 JavaPoet创建java源代码。 Square 的框架真的很棒.请在 GitHub 上查看.

首先,我们需要我们的 metacode实现 HelloMetacode .为此,我们将向 builder 添加 super 接口(interface)。 :

MetacodeContext context = roundContext.metacodeContext();
ClassName masterClassName = ClassName.get(context.masterElement());
builder.addSuperinterface(ParameterizedTypeName.get(
ClassName.get(HelloMetacode.class), masterClassName));

接下来,执行 HelloMetacode通过创建 void setHello(M master)方法:
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("setHello")
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.returns(void.class)
.addParameter(masterClassName, "master");

最后,用 Hello 注释的每个元素的语句, 那 Jeta传入 process方法通过 roundContext范围:
for (Element element : roundContext.elements()) {
String fieldName = element.getSimpleName().toString();
methodBuilder.addStatement("master.$L = \"Hello, Jeta\"", fieldName);
}

这是完整的 SayHelloProcessor list :
package org.brooth.jeta.samples.apt;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeSpec;
import org.brooth.jeta.apt.MetacodeContext;
import org.brooth.jeta.apt.RoundContext;
import org.brooth.jeta.apt.processors.AbstractProcessor;

import javax.lang.model.element.Element;
import javax.lang.model.element.Modifier;

public class SayHelloProcessor extends AbstractProcessor {

public SayHelloProcessor() {
super(Hello.class);
}

@Override
public boolean process(TypeSpec.Builder builder, RoundContext roundContext) {
MetacodeContext context = roundContext.metacodeContext();
ClassName masterClassName = ClassName.get(context.masterElement());
builder.addSuperinterface(ParameterizedTypeName.get(
ClassName.get(HelloMetacode.class), masterClassName));

MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("setHello")
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.returns(void.class)
.addParameter(masterClassName, "master");

for (Element element : roundContext.elements()) {
String fieldName = element.getSimpleName().toString();
methodBuilder.addStatement("master.$L = \"Hello, Jeta\"", fieldName);
}

builder.addMethod(methodBuilder.build());
return false;
}
}

第 5 步:元代码

生成代码所需的所有类都已创建,我们已准备好尝试。但首先,我们需要添加 jeta.properties用于配置 Jeta 的文件.您可以找到有关此文件的更多详细信息 on this page .该文件应位于根包中。对于我们的教程,它的内容是:
metasitory.package=org.brooth.jeta.samples
processors.add=org.brooth.jeta.samples.apt.SayHelloProcessor

接下来修改 SayHelloApp .而不是初始化 text我们将输入的字段 Hello注释:
public class SayHelloApp {
@Hello
String text;
}

build.gradle :
group 'org.brooth.jeta-samples'
version '1.0'

buildscript {
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath 'net.ltgt.gradle:gradle-apt-plugin:0.5'
}
}

apply plugin: 'net.ltgt.apt'
apply plugin: 'java'

sourceCompatibility = 1.7

repositories {
mavenCentral()
jcenter()
}

compileJava {
options.sourcepath = files('src/main/java')
}

dependencies {
apt project(':apt')
compile project(':common')
compile 'org.brooth.jeta:jeta:+'
}

现在我们准备生成元代码。在控制台中运行下一个命令:
./gradlew assemble

如果到目前为止没有问题,我们会看到 SayHelloApp_Metacode app/build 下的文件目录:

SayHelloApp_Metacode

第 6 步: Controller

Controllers是将元代码应用于 masters 的类.让我们为 HelloMetacode 创建一个在 app模块:
 package org.brooth.jeta.samples;

import org.brooth.jeta.MasterController;
import org.brooth.jeta.metasitory.Metasitory;

public class SayHelloController<M> extends MasterController<M, HelloMetacode<M>> {

public SayHelloController(Metasitory metasitory, M master) {
super(metasitory, master, Hello.class, false);
}

public void setHello() {
for (HelloMetacode<M> metacode : metacodes)
metacode.setHello(master);
}
}

第 7 步:元助手
MetaHelper是一个简单的静态助手类。如果您对静态助手不满意,则不应在项目中使用它。您可以在 this page 上阅读有关该类(class)的更多详细信息.

无论如何,让我们创建 MetaHelperapp模块:
package org.brooth.jeta.samples;

import org.brooth.jeta.metasitory.MapMetasitory;
import org.brooth.jeta.metasitory.Metasitory;

public class MetaHelper {

private static MetaHelper instance;
private final Metasitory metasitory;

public static MetaHelper getInstance() {
if (instance == null)
instance = new MetaHelper("org.brooth.jeta.samples");
return instance;
}

private MetaHelper(String metaPackage) {
metasitory = new MapMetasitory(metaPackage);
}

public static void setHello(Object master) {
new SayHelloController<>(getInstance().metasitory, master).setHello();
}
}

请注意,我们必须传递给 MapMetasitory我们指定为 "org.brooth.jeta.samples" 的相同包 ( metasitory.package )在 jeta.properties .

第 8 步:使用

最后一步 - 我们调用 MetaHelper的方法。这是 SayHelloApp 的完整列表:
package org.brooth.jeta.samples;

public class SayHelloApp {

@Hello
String text;

public SayHelloApp() {
MetaHelper.setHello(this);
}

public void sayHello() {
System.out.print(text);
}

public static void main(String[] args) {
new SayHelloApp().sayHello();
}
}

最后,我们可以运行 SayHelloApp .在控制台中,我们应该看到:
Hello, Jeta

链接
  • 本教程关于 GitHub
  • Jeta Website
  • Jeta on Android

  • 快乐的代码生成! :)

    关于java - Jeta:如何创建自定义注释处理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37210107/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com