专栏首页白石Groovy 使用Builder AST 转换为流式API
原创

Groovy 使用Builder AST 转换为流式API

从Groovy 2.3开始,我们可以使用@Builder AST转换轻松地为我们的类创建一个流畅的API。 我们可以将注释应用于我们的类,结果类文件将具有支持流畅API的所有必要方法。 我们可以自定义如何使用不同的注释参数生成流畅的API。 在Groovy代码中,我们已经可以使用with方法 有一个简洁的方法来设置属性值或使用 命名的构造函数参数。 但是如果我们的类需要从Java中使用,那么为Java开发人员提供一个流畅的API来为我们的Groovy类做很好。

在下面的示例中,我们将@Builder注释应用于具有一些属性的简单类Message。 我们将所有内容保留为默认设置,然后生成的Message类文件将有一个新的builder方法,该方法返回一个内部帮助器类,我们可以使用它来设置我们的属性。 对于每个属性,它们是一个带有属性名称的新方法,因此我们可以设置一个值。 最后,我们的类包含一个build,它将返回一个具有正确属性值的Message类的新实例。

import groovy.transform.builder.Builder

@Builder
class Message {
    String from, to, subject, body
}

def message = Message
        .builder()  // New internal helper class.
        .from('mrhaki@mrhaki.com')  // Method per property.
        .to('mail@host.nl')
        .subject('Sample mail')
        .body('Groovy rocks!')
        .build()  // Create instance of Message

assert message.body == 'Groovy rocks!'
assert message.from == 'mrhaki@mrhaki.com'
assert message.subject == 'Sample mail'
assert message.to == 'mail@host.nl'
//If we want to change the names of the builder and build methods we can 
//use the annotation parameters builderMethodName andbuildMethodName:

import groovy.transform.builder.Builder

@Builder(builderMethodName = 'initiator', buildMethodName = 'create')
class Message {
    String from, to, subject, body
}

def message = Message.initiator()
        .from('mrhaki@mrhaki.com')
        .body('Groovy rocks!')
        .create()

assert message.body == 'Groovy rocks!'
assert message.from == 'mrhaki@mrhaki.com'
//We see that for each property a corresponding method is generated. We 
//can also customize the prefix for the generated method name with the 
//annotation parameter prefix. In the following sample we define the 
//prefix assign for the method names:

import groovy.transform.builder.Builder

@Builder(prefix = 'assign')
class Message {
    String from, to, subject, body
}

def message = Message.builder()
        .assignFrom('mrhaki@mrhaki.com')
        .assignBody('Groovy rocks!')
        .build()

assert message.body == 'Groovy rocks!'
assert message.from == 'mrhaki@mrhaki.com'
//Finally we can also include and exclude properties to need to be 
//included or excluded from our fluent API. We use the annotation //parametersincludes and excludes to define the names of the properties. 
//This can be a list or a comma separated list of names.

import groovy.transform.builder.Builder

@Builder(excludes = 'body' /* or includes = 'from,to,subject' */)
class Message {
    String from, to, subject, body
}

def message = Message.builder()
        .from('mrhaki@mrhaki.com')
        .to('mail@host.nl')
        .subject('Groovy 2.3 is released')
        .build()

assert message.from == 'mrhaki@mrhaki.com'
assert message.subject == 'Groovy 2.3 is released'

try {
    message = Message.builder().body('Groovy rocks!').build()
} catch (MissingMethodException e) {
    assert e.message.readLines().first() ==
            'No signature of method: static Message.body() is applicable for argument types: (java.lang.String) values: [Groovy rocks!]'
}

@Builder AST转换还检查@Canonical AST转换是否应用于类。 对于生成的构建器代码,还包括或排除在@Canonical转换中定义的任何包含或排除的属性。

我们可以使用builderStrategy注释参数定义SimpleStrategy策略。 然后生成的类将没有单独的内部帮助器构建器类和构建方法。 默认的prefix设置为set,但如果我们想要,我们可以更改:

import groovy.transform.builder.Builder
import groovy.transform.builder.SimpleStrategy

@Builder(builderStrategy = SimpleStrategy, prefix = 'assign')
class Message {
    String from, to, subject, body
}

def message = new Message()
        .assignFrom('mrhaki@mrhaki.com')  // Method per property.
        .assignTo('mail@host.nl')
        .assignSubject('Sample mail')
        .assignBody('Groovy rocks!')

assert message.body == 'Groovy rocks!'
assert message.from == 'mrhaki@mrhaki.com'
assert message.subject == 'Sample mail'
assert message.to == 'mail@host.nl'

我们将在未来的博客文章中看到@ Builder注释的其他功能。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Groovy 元组构造函数创建

    Groovy 1.8添加了@TupleConstructor注释。 通过这个注释,我们可以在编译时自动创建一个元组构造函数。 因此构造函数可以在编译的类中找到。...

    白石
  • Groovy中 Base64 URL和文件名安全编码

    Groovy支持Base64编码很长一段时间。 从Groovy 2.5.0开始,我们还可以使用Base64 URL和Filename Safe编码来使用enco...

    白石
  • Groovy中 使用Tap方法轻松创建对象

    Groovy 2.5.0将tap方法添加到所有对象并更改with方法的方法签名。 在上一篇文章 中,我们已经了解了with方法。在Groovy 2.5.0中,我...

    白石
  • Message Pool分析

    Android中,我们在线程之间通信传递通常採用Android的消息机制,而这机制传递的正是Message。

    蜻蜓队长
  • RocketMQ ACL使用指南

    RocketMQ在4.4.0版本开始支持ACL。ACL是access control list的简称,俗称访问控制列表。访问控制,基本上会涉及到用户、资源、权限...

    丁威
  • 基于白名单 Regasm.exe 执行 Payload 第三季

    Regasm为程序集注册工具,读取程序集中的元数据,并将所需的项添加到注册表中。RegAsm.exe是Microsoft Corporation开发的合法文件进...

    洛米唯熊
  • Chef 的安装与使用

    Chef 是一款自动化服务器配置管理工具,可以对所管理的对象实行自动化配置,如系统管理,安装软件等。Chef 由三大组件组成:Chef Server、Chef ...

    菲宇
  • 前端周记 2017 年终总结

    2016年末的时候,给自己定了个小目标——2017年每周发布一篇前端相关的文章。于是时间很快到了今天——2017年的最后一周最后一天了——发布最后一篇文章。 算...

    企鹅号小编
  • SAP中使用本地打印机的设置

    3, 在出现的界面中,先点击修改按钮,然后点击新建,出现如下界面,按图中所示进行设置。

    用户5495712
  • MIT教你创造让人“雌雄难辨”的图灵机器,秘密全在这篇论文里

    GAIR 今年夏天,雷锋网将在深圳举办一场盛况空前的“全球人工智能与机器人创新大会”(简称GAIR)。大会现场,谷歌,DeepMind,Uber,微软等巨头的人...

    AI科技评论

扫码关注云+社区

领取腾讯云代金券