概述
Grails 简介:Grails 是一个开源的 Web 开发框架,它采用动态语言 Groovy 进行开发,并且可以和用 Java 开发的项目进行集成。Grails 充分体现了约定优于配置的原则,将项目的配置减到最低。目前主流的 Java Web 框架都过于复杂,如 Structs、Spring、Webwork,这些框架的用户都需要编写和维护许多配置文件,并且用这些框架的项目写法各有不同,没有统一的标准。Grails 的出现解决了这些问题,用户可以发现在 Grails 中很少去修改和添加配置文件。
Maven 简介:Maven 是一个项目管理工具,基于项目对象模型(Project Object Model),Maven 可以管理项目的构建、报告和文档的生成。Maven 主要用于用 Java 进行开发的项目。
Grails 对于 Maven 的支持:在 Grails 2.1 以前,Grails 插件必须在 BuildConfig.groovy 文件配置,对 Java 的依赖必须在 pom 文件中指定。
在 Grails 2.1 以后,对 Maven 集成的支持有了大的改进,现在 pom 文件也支持引用 Grails 插件,如清单 1:
清单 1. pom.xml 对 Grails 的支持
<dependency> <groupId>org.grails.plugins</groupId> <artifactId>hibernate</artifactId> <version>2.1.0.RC1</version> <type>zip</type> <scope>compile</scope> </dependency>
Maven 插件现在可以识别 Grails 依赖的其它插件和 Jar 包。并且 Grails 增加了一个新的命令:create-multi-project-build,这个命令在包括多个 Grails 应用或插件的目录中被调用,会生成对复杂项目的 Maven 构建。在 Grails2.1 后,对已有 Grails 项目的 Maven 管理,也只需要输入 create-pom 命令来创建项目对应的 pom 文件。
开发环境:Grails 2.1、Maven 3、JDK1.6。
回页首
单个 Grails 项目与 Maven 的集成
首先运行 create-app 命令来生成 Grails 项目,接着在 Grails 项目的根目录下用命令 create-pom 生成 POM 文件。具体实例如清单 2:
清单 2. 用命令 create-pom 生成 POM 文件
#> grails create-app my-app #> cd my-app #> grails create-pom build.groupid
我们对上面三条命令进行简要说明,第一条是 Grails 项目的创建命令,这个命令将会以用户指定的名称来创建 Grails 应用,我们指定的名称是 my-app,所以会生成名称为 my-app 的 Grails 应用。第二条命令是进入我们创建的 my-app 的根目录下,因为第三条命令需要在 Grails 的根目录下运行。第三条命令是为 Grials 应用创建 POM 文件,使得 Grails 应用可以用 Maven 进行构建,参数 groupid 是指定应用隶属的项目。
运行 create-pom 命令后,我们可以看到在 my-app 根目录生成了文件 pom.xml, 文件显示如清单 3:
清单 3. 在 my-app 根目录生成的 pom.xml 文件
<?xml version="1.0" encoding="utf-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>build.groupid</groupId> <artifactId>my-app</artifactId> <packaging>grails-app</packaging> <version>0.1</version> <name>my-app</name> <description>0.1</description> ...... </project>
现在可以运行 mvn 的命令做简单测试,如:mvn package, 可以看到结果如清单 4:
清单 4. 运行 mvn 的命令做简单测试
|Loading Grails 2.1.0 |Configuring classpath |Running pre-compiled script . |Environment set to prod ................................. |Packaging Grails application .... |Compiling 1 source files ............ |Compiling 3 GSP files for package [myApp] .. |Compiling 4 GSP files for package [databaseMigration] .. |Building WAR file .......................................... |Done creating WAR target\my-app-0.1.war [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2:13.841s [INFO] Finished at: Tue Oct 16 13:31:29 CST 2012 [INFO] Final Memory: 16M/34M [INFO] ------------------------------------------------------------------------
从结果可以看出,我们可以使用 Maven 的命令来构建 Grails 项目。其它的 Maven 的标准命令也可以运行。例如清单 5 的命令:
清单 5. 其它的 Maven 的标准命令
compile – 编译 Grails 项目 package – 构建生成 war 文件 install – 构建生成 war 文件并且将其安装在你本地的 Maven 库中 test – 运行项目的测试 clean- 清理 Grails 项目
我们对 Maven 命令执行的流程做简要说明。当在项目的根目录下输入 mvn clean package 时,maven 会将这个命令委托给 grails maven 插件来调用 grails clean 和 grails package 这两个命令。当运行这些命令时,所有的依赖来自于 Maven 的配置文件而非 Grails 的配置文件。
表 1. POM 文件内容的说明
属性 | 说明: |
---|---|
modelVersion | POM 模型的版本,Maven2/3 的话,值为 4.0.0 |
groupId | 项目所属的组,一般项目都是由几个模块组成,所以各个模块所属的项目(组)由此参数设定。 |
artifactId | 项目在组中的定义,和 Grails 项目根目录下 application.properties 中的 app.name 名字一致。 |
packaging | 值为 grails-app,指出应用是 Grails 的应用,所以打包时会以 Grails 的应用打包。 |
version | 项目当前版本,必须和 application.properties 中的 app.version 内容一致。 |
name | 项目的名称。 |
description | 项目的描述。 |
properties | 设置 Grails 的版本号。 |
dependencies | 当运行命令 create-pom 时, grails 会基于 BuildConfig.groovy 在 POM 文件中生成项目所依赖的包,插件等。 |
build | 构建的设置。 这一部分包括了构建 Grails 项目的 Maven 插件。 |
repositories | 项目的仓库设置。 Grails 有自己的 Maven 仓库来存储插件和它的核心依赖。 |
profiles | 自定义构建环境。 |
回页首
Maven Archetype 的使用
上面讲的是在已有的 Grails 项目中集成 Maven,我们也可以用 maven 的 Archetype 生成 Grails maven 项目。当用 archetype 时,我们无需安装 Grails, 只需输入下面的命令,如清单 6:
清单 6. 用 maven 的 Archetype 生成 Grails maven
mvn archetype:generate -DarchetypeGroupId=org.grails -DarchetypeArtifactId=grails-maven-archetype -DarchetypeVersion=2.1.0 -DgroupId=example -DartifactId=my-app
使用 maven archetype 命令后,可以快速的生成项目的骨架。其中参数 DarchetypeGroupId , DarchetypeArtifactId 和 DarchetypeVersion 指定了以 Grails 2.1 的模板生成项目骨架。 DgroupId 和 DartifactId 参数指定要创建应用的 GroupId 以及 artifactId,我们没有指定应用的版本,所以当运行这个命令后,会提示输入 version。当输入提示需要输入的值并最后输入“Y“按回车键时,会生成一个新的 Maven 项目。在这个项目中会生成 POM 文件,src 文件夹以及其它文件。在生成的项目骨架中,我们看到并不像 Grails 项目的结构,所以我们需要修改 POM 文件并运行 mvn initialize 命令。
打开 my-app/pom.xml,找到 maven-compiler-plugin, 如清单 7 所示:
清单 7. 找到 maven-compiler-plugin
<plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin>
我们需要将 JDK 的版本从 1.5 改为 1.6,因为我们本地安装的是 JDK1.6。然后我们输入命令 mvn initialize:如下图所示:
图 1. 输入命令 mvn initialize
当此命令执行完后,我们打开 my-app 目录,会发现一个完整的 grails 项目结构目录已经生成。
回页首
多模块 Grails 项目与 Maven 集成
首先创建 3 个 Grails 项目,命令如下:
图 2. 创建 3 个 Grails 的命令
接着我们用命令 create-multi-project-build 来使多模块项目与 Maven 集成。
图 3. 多模块项目与 Maven 集成
当此命令运行完后,在当前目录下会生成一个 pom.xml,并且在前面创建的三个项目文件夹下生成 pom.xml。
当前目录的 pom.xml 文件显示如清单 8:
清单 8. 当前目录的 pom.xml 文件
<?xml version="1.0" encoding="utf-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.mycompany</groupId> <artifactId>parent</artifactId> <packaging>pom</packaging> <version>1.0</version> <name>parent</name> <modules> <module>myapp</module> <module>plugin1</module> <module>plugin2</module> </modules> </project>
三个子项目下的 pom.xml 文件如下,以 myapp 目录下的 pom.xml 为例:
清单 9. 当前目录的 pom.xml 文件
<?xml version="1.0" encoding="utf-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.mycompany</groupId> <artifactId>parent</artifactId> <version>1.0</version> <relativePath>..</relativePath> </parent> <groupId>org.mycompany</groupId> <artifactId>myapp</artifactId> <packaging>grails-app</packaging> <version>0.1</version> ...... </project>
首先对当前目录下的 POM 文件进行分析,从 POM 文件中可以看到 groupId, artifactId 和 version 都是用命令 create-multi-project-build 时传的参数。packaging 被设置成 pom 来指出它有子模块。modules 标签列出了所包含的子模块,因为我们前面创建了 3 个模块,所以这里列出了 3 个子模块。
下面我们对模块中的 POM 文件进行分析。
先看下 plugin1 下面的 pom.xml,在这个文件里首先是 parent 标签。Parent 标签的内容中 groupId,artifactId,version 的值和父 pom.xml 中相同。relativePath 指定了父 POM 文件的位置,所以根据这些配置可以找到父 POM 文件。Parent 标签下面是子模块的 groupId,artifactId,version 的设置,这里我们注意到 plugin 的 groupId 默认值是 org.grails.plugins。并且 packaging 的值为 grails-plugin。Plugin2 下面的 pom.xml 文件和 plugin1 下面的相似,所以不再做分析。
对于 myapp 文件夹下的 pom 文件,可以看到 parent 的值也是指向父 pom 文件。packaging 值为 grails-app,指出这是 Grails 的应用。在此 POM 文件中,我们会发现 dependency 有下面的设置:
清单 10. 当前目录的 pom.xml 文件
<dependency> <groupId>org.grails.plugins</groupId> <artifactId>plugin1</artifactId> <version>0.1</version> <type>zip</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.grails.plugins</groupId> <artifactId>plugin2</artifactId> <version>0.1</version> <type>zip</type> <scope>compile</scope> </dependency>
这里的设置指定了 myapp 依赖于 plugin1 和 plugin2。
下面我们运行 mvn install 来进行测试,可以看到构建的顺序,先根据当前目录下 parent 的值为 pom 知道这个是多模块的构建,然后去查找子模块的 pom.xml,根据子模块的 pom 文件进行构建。由于子模块 myapp 依赖于 plugin1 和 plugin2,所以 plugin1 和 plugin2 会先被构建。
图 4. 构建 plugin1 和 plugin2
回页首
Grails Plugin 与 Maven 集成
这里我们对 grails plugin 的构建做一下简要说明。Plugin 创建时用命令 grails create-plugin plugin_name, 创建 pom 文件的命令和一般应用相同,都是 create-pom。对于 pom 文件,主要的区别是 packaging 的值不同。plugin 的值为 grails-plugin,app 的值为 grails-app。这个设置使得 plugin 在构建时会调用其对应的构建命令。
Grails 插件可以被安装在其它应用中。如果我们用 IDE 打开 Grails 项目,可以看到在 Plugins 目录下,默认已经安装了 cache、hibernate、jquery、resources 等插件。
回页首
总结
通过本文对 Grails 与 Maven 集成的介绍,可以看到 Grails 项目创建完成后,开发者如何用 Maven 来进行构建。目前大多数的 Java 项目会采用 Maven 进行构建管理,所以当 Grails 项目模块是整个项目的一部分时,采用 Maven 对 Grails 项目进行统一管理,会使得对整个项目的构建管理一致。一般在单个 Grails 项目时,会采用 Grails 自身的构建机制进行构建。