显示导航

在 Grails 应用中使用 SpringBoot @ConfigurationProperties

Grails 3 应用是 Spring Boot 应用。了解如何通过 @ConfigurationProperties 将属性值绑定到结构化对象。

作者:Sergio del Amo

Grails 版本 3.3.8

1 培训

Grails 培训 - 由创建和积极维护 Grails 框架的人员开发和交付!。

2 入门

在本指南中,我们将创建一个通过下载包含书籍列表的 Excel 文件来演示 Grails 文件传输功能的应用。

2.1 您需要的信息

要完成本指南,您需要以下内容

  • 一些时间

  • 一个出色的文本编辑器或 IDE

  • JDK 1.8 或更高版本以及相应配置的 JAVA_HOME

2.2 解决方案

我们建议您按照下一部分中的说明逐步创建应用。但是,您可以直接转到完成的示例

然后,进入下载/克隆的项目的根项目中的 complete 文件夹。

3 编写应用

grails create-app example.grails.complete --features=events,geb2,hibernate5

我们在使用包括 Geb 2Gradle WebDriver Binaries 插件geb2 功能。Geb 2 需要 JDK 1.8 或更高版本。

3.1 配置属性

在本部分中,我们将探讨如何通过 @ConfigurationProperties 将属性值绑定到结构化对象。

首先,我们需要用 @ComponentScan 注释 Application.groovy

grails-app/init/example/grails/Application.groovy
package example.grails

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import groovy.transform.CompileStatic
import org.springframework.context.annotation.ComponentScan

@CompileStatic
@ComponentScan (1)
class Application extends GrailsAutoConfiguration {
    static void main(String[] args) {
        GrailsApp.run(Application, args)
    }
}
1 @ComponentScan 告诉 Spring 在指定包中查找其他组件、配置和服务。Spring 能够自动扫描、检测和注册预定义项目包中的 bean 或组件。如果没有指定包,则当前类包将作为根包。

创建一个名为 AddressConfiguration.groovy 的文件。

src/main/groovy/example/grails/AddressConfiguration.groovy
package example.grails

import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Component

@Configuration (1)
@ConfigurationProperties(prefix = "address") (2)
class AddressConfiguration {
    String street
    String city
    String country
}
1 我们添加了 @Configuration 注解,以便 Spring 能够找到此 bean 并将其设为注入候选对象。
2 @ConfigurationProperties 注解采用配置前缀。

在属性文件中定义的任何具有前缀 address 并且与某个属性同名的属性都会自动分配给这个对象。

application.yml 添加一些属性。

grails-app/conf/application.yml
address:
    street: 221B Baker Street
    city: London
    country: United Kingdom

3.2 Tag Lib

创建一个 标签库 来呈现地址

grails-app/taglib/example/grails/AddressTagLib.groovy
package example.grails

class AddressTagLib {

    static namespace = "app" (1)

    AddressConfiguration addressConfiguration (2)

    def address = { attrs, body ->
        out << """\
<div class='adr'>
    <div class='street-address'>${addressConfiguration.street}</div>
    <span class='locality'>${addressConfiguration.city}</span>,
    <div class='country-name'>${addressConfiguration.country}</div>
</div>""" (3)
    }
}
1 默认情况下,标签会添加到默认的 Grails 名称空间中,并且在 GSP 页面中以 g: 前缀使用。但是,您可以通过向 TagLib 类添加静态属性来指定其他名称空间。
2 可以像对其他任何 bean 一样将 AddressConfiguration 注入到 TagLib 中。
3 创建一个有效的 adr 微格式 HTML 代码段。

3.3 单元测试

为 TagLib 创建一个单元测试

src/test/groovy/example/grails/AddressTagLibSpec.groovy
package example.grails

import grails.testing.web.taglib.TagLibUnitTest
import spock.lang.Specification

class AddressTagLibSpec extends Specification implements TagLibUnitTest<AddressTagLib> { (1)

    Closure doWithSpring() {{ -> (2)
        addressConfiguration(AddressConfiguration)
    }}

    void "test address tag"() {
        when:
        String returnString = tagLib.address().toString() (3)

        then:
         returnString == "<div class='adr'>\n    <div class='street-address'>221B Baker Street</div>\n    <span class='locality'>London</span>,\n    <div class='country-name'>United Kingdom</div>\n</div>"
    }
}
1 标签库和 GSP 页面可以使用 grails.testing.web.taglib.TagLibUnitTest 特性来进行测试。
2 要提供或替换上下午中的 bean,您可以在测试中覆盖 doWithSpring 方法。
3 向测试添加 TagLibUnitTest 特性会导致自动为测试的 TagLib 类创建一个新的 tagLib 字段。tagLib 属性可用于测试将标签调用为函数调用。

3.4 验收测试

编辑 grails-app/views/index.gsp,即访问主页 / 和添加以下代码段时呈现的 GSP

grails-app/views/index.gsp
...
 <div id="content" role="main">
 ....
 ...
         <app:address/>
 </div>
 ...

现在可以使用 Geb 创建一个验收测试,以验证地址已呈现到主页上

src/integration-test/groovy/example/grails/AddressSpec.groovy
package example.grails

import geb.spock.GebSpec
import grails.testing.mixin.integration.Integration
import spock.lang.IgnoreIf

@Integration
class AddressSpec extends GebSpec {

    @IgnoreIf({ !sys['geb.env'] })
    def "verify address is displayed in homepage"() {
        when:
        browser.go("/")

        then:
        browser.driver.pageSource.contains('221B Baker Street')
    }
}

4 测试应用

运行测试

./grailsw
grails> test-app
grails> open test-report

./gradlew check
open build/reports/tests/index.html

5 帮助使用 Grails

Object Computing, Inc. (OCI) 赞助了本指南的创建。提供各类咨询和支持服务。

OCI 是 Grails 的所在地

认识团队