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 解决方案
我们建议你按照下一部分说明分步创建应用程序。但是,你可以直接转到完整示例。
-
下载并解压源代码
或
-
克隆 Git 存储库:
git clone https://github.com/grails-guides/grails-configuration-properties.git
然后,cd
进入下载/克隆项目的根项目中找到的 complete
文件夹。
3 编写应用程序
grails create-app example.grails.complete
3.1 配置属性
在本节中,我们将探讨如何通过 @ConfigurationProperties
将属性值绑定到结构化对象。
首先,我们需要注解 Application.groovy
,加 @ComponentScan
。
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` 的文件。
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` 添加一些属性。
address:
street: 221B Baker Street
city: London
country: United Kingdom
3.2 标签库
创建 标签库 以呈现地址。
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 创建单元测试
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,然后添加以下片段。
...
<div id="content" role="main">
....
...
<app:address/>
</div>
...
现在,我们可以使用 Geb 创建验收测试,以验证地址在主页中是否已呈示。
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