简述Gradle在大型Java项目上的应用---环境的配置(二)

  1. 环境的配置

为了方便地将应用部署到开发、测试以及产品等不同环境上, Gradle提供了几种不同的方式为不同的环境打包,使得不同的环境可以使用不同的配置文件。此外,它还提供了简单的方法,使得我们能够便捷地初始化数据库 。

2.1 Properties配置

要为不同的环境提供不一样的配置信息,Maven选择使用profile,而Gradle则提供了两种方法为构建脚本提供Properties配置:

第一种方式是使用传统的properties文件, 然后在使用Gradle时,通过传入不同的参数加载不同的properties文件。例如,我们可以在项目中提供development.properties、test.properties和production.properties。在项目运行时,使用-Pprofile=development来指定加载开发环境的配置。构建脚本中加载properties文件的代码如下:

ext {
profile = project[‘profile’]
}
def loadProperties(){
def props = new Properties()
new File(“ rootProject.projectDir/config/ {profile}.properties”)
.withInputStream {
stream -> props.load(stream)
}
props
}
在运行脚本的时候,传入的-Pprofile=development可以指定使用哪个运行环境的配置文件。代码中使用了project[‘profile’]从命令行里读取-P传入的参数,Gradle会去父项目根目录下的config文件夹中需找对应的properties文件。

另外一种方式就是使用Groovy的语法,定义可读性更高的配置文件。比如可以在项目中定义config.groovy的配置文件,内容如下:

environments {
development {
jdbc {
url = ‘development’
user = ‘xxxx’
password = ‘xxxx’
}
}

test {
    jdbc {
        url = 'test'
        user = 'xxxx'
        password = 'xxxx'
    }
}

production {
    jdbc {
        url = 'production'
        user = 'xxxx'
        password = 'xxxx'
    }
}

}
这里定义了三个环境下的不同数据库配置,在构建脚本中使用如下的代码来加载:

ext {
profile = project[‘profile’]
}

def loadGroovy(){
def configFile = file(‘config.groovy’)
new ConfigSlurper(profile).parse(configFile.toURL()).toProperties()
}
这里在ConfigSlurper的构造函数里传入从命令行里取到的-P的参数。调用loadGroovy方法就可以加载项目根目录下的config.groovy文件,并作为一个Map返回,这样就可以通过jdbc.url来获取url的值。

从可读性以及代码整洁(配置文件也需要代码整洁)而言,我推荐使用第二种方式来配置,因为这种方法具有清晰的结构。如上面的例子,就可以把数据库相关的信息都放在jdbc这个大的节点下,而不用像properties文件这样的扁平结构。但是对于一些已经使用properties文件来为不同环境提供配置信息的遗留项目里,使用properties文件也没有问题。

2.2 替换

通过不同的方式加载不同环境的配置后,就需要把它们替换到有占位符的配置文件中去。在配置文件中使用@key@来标注要被替换的位置,比如在config文件夹中有jdbc.properties文件,其内容如下:

jdbc.url=@jdbc.url@
jdbc.user=@jdbc.user@
jdbc.password=@jdbc.password@
在Gradle构建过程中,有一个processResources的Task,可以修改该Task的配置,让其在构建过程中替换资源文件中的占位符:

processResources {
from(sourceSets.main.resources.srcDirs) {
filter(org.apache.tools.ant.filters.ReplaceTokens,
tokens: loadGroovyConfig()
)
}
}
上面这种做法用来处理子项目src/main/resources文件夹下的资源文件,所以需要将这段代码放在子项目的独立配置文件里。

在一些复杂的项目中,经常会把配置文件放置到一个目录进行统一管理。比如在我所在的项目,就专门提供了一个config子目录,里面存放了所有的配置信息。在处理这些资源文件时, Gradle默认提供的processResources就不够用了,我们需要在Gradle脚本中定义一个Task去替换这些包含占位符的配置文件,然后让package或者deploy的Task依赖这个Task。该Task的代码如下:

task replace(type: Sync) {
def configHome = “${project.rootDir}/config”

from(configHome) {
    include '**/*.properties'
    include '**/*.xml'
    filter org.apache.tools.ant.filters.ReplaceTokens, 

tokens: loadGroovyConfig()
}
into “${buildDir}/resources/main”
}
这里定义了一个Sync类型的Task,会将父项目的根目录下的config文件夹的所有properties和xml文件使用从loadGroovyConfig()方法中加载出来的配置替换,并将替换之后的文件放到build文件夹下的resource/main目录中。再让打包的Task依赖这个Task,就会把替换之后的配置文件打到包中。

2.3 更复杂的情况

上面介绍了在项目中如何使用Gradle处理 properties和xml文件中具有相同配置,但其中的一些值并不相同的情况 。然而,在有些项目中不同的环境配置之间变化的不仅是值,很有可能整个配置文件都不相同;那么,使用上面替换的处理方式就无法满足要求了。

在我所在的项目中,我们需要依赖一个外部的Web Service。在开发环境上,我们使用了Stub来模拟和Web Service之间的交互,为开发环境提供测试数据,这些数据都放置在一个Spring的配置文件中;而在测试和产品环境上,又要使用对应的测试和产品环境的Web Service。这时,开发、测试与产品环境的配置完全不同。对于这种复杂的情况,Gradle可以在构建过程中为不同的环境指定不同的资源文件夹,在不同的资源文件夹中包含不同的配置文件。

例如,在我们项目的config目录下包含了application文件夹,定义了不同环境所需的不同配置文件,其目录结构如下图所示:

在构建脚本中,根据从命令行读入的-P参数,使用不同的资源文件夹,其代码如下:

sourceSets {
main {
resources {
srcDir “config/application/spring/ profile,config/application/properties/ {profile}”
}
}
}
这样在打包的过程中,就可以使用-P传入的参数的资源文件夹下面的properties和xml文件作为项目的配置文件。

2.4 初始化数据库

在项目开发过程中,为了方便为不同环境构建相同的数据库及数据,我们通常需创建数据库的表以及插入一些初始化数据。Gradle目前没有提供相关的Task或者Plugin,但是我们可以自己创建Task去运行SQL来初始化各个环境上的数据库。

前面也提到Gradle是Groovy定义的DSL,所以我们可以在Gradle中使用Groovy的代码来执行SQL脚本文件。在Gradle脚本中,使用Groovy加载数据库的Driver之后,就可以使用Groovy提供的Sql类去执行SQL来初始化数据库了。代码如下:

groovy.sql.Sql oracleSql =
Sql.newInstance(props.getProperty(‘database.connection.url’),
props.getProperty(‘database.userid’),
props.getProperty(‘database.password’),
props.getProperty(‘database.connection.driver’))

try {
new File(script).text.split(“;”).each {
logger.info it
oracleSql.execute(it)
}
} catch (Exception e) { }
这段代码会初始化执行SQL的groovy.sql.Sql对象,然后按照分号(;)分割SQL脚本文件里的每一条SQL并执行。对于一些必须运行成功的SQL文件,可以在catch块里通过抛出异常来中止数据库的初始化。需要注意的是需要将数据库的Driver加载到ClassPath里才可以正确地执行。

因为在Gradle中包含了Ant,所以我们除了使用Groovy提供的API来执行SQL之外,还可以使用Ant的sql任务来执行SQL脚本文件。但若非特殊情况,我并不推荐使用Ant任务,这部分内容与本文无关,这里不再细述 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值