显示导航

Grails 应用程序中的 SpringBoot @ConfigurationProperties

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

作者:Sergio del Amo

Grails 版本 5.0.1

1 培训

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

2 开始

在本指南中,我们将展示 Grails 文件传输功能,方法是创建一个应用程序,该应用程序会下载包含一组书籍的 excel 文件。

2.1 你需要什么

要完成本指南,你需要满足以下条件

  • 要有些时间

  • 合适的文本编辑器或 IDE

  • JDK 1.8 或更高版本,且已正确配置 JAVA_HOME

2.2 解决方案

我们建议你按照下一部分说明分步创建应用程序。但是,你可以直接转到完整示例

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

3 编写应用程序

grails create-app example.grails.complete

3.1 配置属性

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

首先,我们需要注解 Application.groovy,加 @ComponentScan

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 我们为 Spring 添加了 `@Configuration` 注解,以便能找到此 bean 并且能将其用作注入候选对象。
2 @ConfigurationProperties 注解采用配置前缀。

属性文件中定义的任何属性,如果具有前缀 address 且名称与其中一个属性相同,则会被自动分配给此对象。

向 `application.yml` 添加一些属性。

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

3.2 标签库

创建 标签库 以呈现地址。

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) {
            street = '221B Baker Street'
            city = 'London'
            country = 'United Kingdom'
        }
    }}

    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 可以使用 `grails.testing.web.taglib.TagLibUnitTest` 特性测试标签库和 GSP 页面。
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 {

    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 的家园

认识团队