使用Gradle整合angular和Spring boot

1. 前言

本文讲述如何使用 Gradle 搭建一个以 springboot 技术栈作为后端, 使用 Angular 作为前端技术栈, 同过 gradle 将其整合成一个项目的实践经验.

这里只是作为一种实践, 并不建议在生产环境中将前后端耦合在一起. 本文的目的是拓展 Spring 在(SPA)Single page Application 一种能力, 即将实现项目依赖关系, 测试,打包等等自动化.

实现思路就是通过 Gradle task 触发 npm build, 将编译后的静态资源文件, 部署到 springboot 的静态资源文件目录, 然后沿用后端打包过程, 将前后端应用程序整合在一起.

2. 前置条件

项目需要用到 Nodejs, angular cli, gradle, 需要提前储备相关知识和安装环境.

3. 创建后端项目

可以使用Spring’s Initializr 工具来快速的创建一个工程.

也可以参考我的文档如何手动创建一个 springBoot 项目, 里面有对 springBoot 项目的详细解释.

4. 创建前端项目

创建完成后端 springboot 项目后, 进入 src/main/目录下创建前端项目.

1
2
3

ng new webapp

对于如何创建 Angular 项目,详细信息可以参考我的博客创建 Angular 项目

5. 使用 gradle 将前后端整合

将 springboot 项目和 angular 项目整合的关键就是: 首先调用 ng build, 将编译后的文件放到 springboot 的 static 目录下.

5.1. 配置 angular 项目

首先我们修改一下 angular 的配置文件 angular.json, 找到 architect.build.options.outputPath 属性, 将其指向 springBoot 项目的 src/resources 目录

这里我们使用相对路径.

1
"outputPath": "../resources/static",

此时我们以及可以手动编译一下前端工程, 看其是否会将编译后的文件输出到指定路径下.

1
2
3
4

cd webapp
ng build

此时我们可以看到编译的结果输出到了 resources/webapp

1
2
3
4
5
6
7
8
9
$tree ../resources/static
static
├── 3rdpartylicenses.txt
├── favicon.ico
├── index.html
├── main.e25f0772ec365244.js
├── polyfills.8e0c5f95042fa80f.js
├── runtime.2ab56e4f659c1314.js
└── styles.ef46db3751d8e999.css

注意这里的 index.html, 当我们在稍后启动了 springboot, 使用浏览器访问http://localhost时首先需要加载的就是这个文件.

5.2. 配置 spring boot 项目

此时我们已经有了 html 文件, 以及 js 等等文件, 我们只需要在 springboot 项目的配置文件中, 将静态资源文件目录指向../resources/webapp.

修改 springboot 项目的配置文件

1
spring.resources.static-locations=classpath:/static

并指定端口号 80, 此项配置是可选的, 默认 springBoot web 会监听在 8080, 此处只是为了方便后续讲解, 所以将端口号修改到 80 端口.

1
server.port= 80

此时我们启动 springBoot

1
./gradlew bootRun

启动成功后, 打开浏览器访问http://localhost 即可看到一个 default 的 angular 应用了.

5.3. 自动化工程

前面的过程中, 我们需要手动执行ng build命令将 web 相关文件输出到 src/resources/static 目录下.

每次编译还需要手动清理文件. 而我们的目标是执行./gradlew bootRun时自动执行这一过程.

将这一段加入到我们 build.gradle 中即可在编译, 打包, 运行之前执行我们手动执行的部分.

代码很好理解, 注释也已经写的很清楚了, 这里就不做过多解释了, 也就是手工过程的替代.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

def webappDir = "$projectDir/src/main/webapp"

processResources {
dependsOn "buildAngular"
}

task buildAngular(type:Exec) {
// installAngular should be run prior to this task
dependsOn "installAngular"
workingDir "$webappDir"
inputs.dir "$webappDir"
// Add task to the standard build group
group = BasePlugin.BUILD_GROUP
// ng doesn't exist as a file in windows -> ng.cmd
if (System.getProperty("os.name").toUpperCase().contains("WINDOWS")){
commandLine "ng.cmd", "build"
} else {
commandLine "ng", "build"
}

}

task installAngular(type:Exec) {
workingDir "$webappDir"
inputs.dir "$webappDir"
group = BasePlugin.BUILD_GROUP
if (System.getProperty("os.name").toUpperCase().contains("WINDOWS")){
commandLine "npm.cmd", "install"
} else {
commandLine "npm", "install"
}
}

完成以上配置我们就可以执行以下命令, 启动 springBoot 项目了, 在浏览器上敲入http://localhost就可以访问基于 Angular 的 SPA 应用了.

1
2
3

./gradlew bootRun

6. Angular 系列文章

最新更新以及更多 Angular 相关文章请访问 Angular 合集 | 鹏叔的技术博客

7. 总结

本文详细讲述了如何创建 springBoot 工程以及 Angular 工程, 并通过 gradle 将前后端工程整合起来. 秘诀就是将 angular 工程的 output 输出到 springboot 的静态资源目录下.

如果要更加深入的探索 Angular 以及 SpringBoot, 可以移步到鹏叔的技术博客https://www.pengtech.net, 空间中提供了博客内搜索功能, 输入相关关键字进行探索吧.

8. 参考文档

Angular + Spring Boot integration using Gradle