spring-cloud documentation
TRANSCRIPT
Spring-Cloud Documentation发布 10
Murphy
2019-12-03
目录
1 Spring Boot Cloud 学习 111 课程进度 112 练习进度 2
2 初识 Maven 321 Maven 介绍 322 多线程 423 跳过测试 424 编译失败后接着编译 425 编译到最后再报错 426 使用 Nexus 本地私服 427 使用 Aliyun 国内镜像 428 指定 Repository 目录 529 Maven Properties 5210 Maven Sources 5211 Maven Proxy 5
2111 命令行设置 52112 配置文件 5
212 Dependency local Jar 6213 Install Jar 6214 MAVEN 属性 6
2141 内置属性 62142 POM 属性 62143 自定义属性属性 72144 setting 属性 72145 Java 系统属性 72146 环境变量属性 7
i
215 MAVEN_OPTS 7216 Nexus Security 7217 Error in Eclipse 8218 参考 8
3 初识 Git 1131 常见 Git 命令 1132 Connecting with SSH 1233 RPC 13
331 Web 13332 SSH 14
34 API 14
4 初识 Docker 1541 介绍 1542 Install 15
421 Centos 15422 Install Docker Compose 15
43 image and compose 1544 command 1645 搭建 DB server 17
451 docker-composeyml 17452 mongo-initsh 18453 startsh 18
46 Issue 19
5 Spring Boot CLI 2151 安装 Spring Boot CLI 21
511 从安装文件中手动安装 21512 使用 SDKMAN 安装 21513 利用 OSX Homebrew 安装 22514 使用 MacPorts 安装 22
52 开始使用 CLI 2253 使用 CLI 初始化项目 2254 参考 23
6 Spring Boot 2x 学习 2561 Spring Boot 概述 2562 常规概念 25
621 PO 26622 BO 26623 VO 26624 POJO 26
ii
625 DTO 26626 DAO 27
63 快速上手 27631 在线界面初始化项目 27632 环境准备 27633 pomxml 28634 添加 Code 28635 运行程序 29
6351 IDE 中执行 296352 mvn 执行 29
636 创建 an Executable Jar 29637 部署 30
64 参考 30
7 Spring Boot Controller 3171 理解 Controller 3172 实现 REST 服务 3173 ResponseEntity 3274 RequestMapping 3275 Controller 中获取参数 33
751 Controller 方法的形参 33752 HttpServletRequest 34753 通过 Bean 接收 34754 PathVariable 35755 ModelAttribute 35756 RequestParam 36757 RequestBody 36758 RequestHeader CookieValue 37
8 Spring Boot Service 3981 理解 Service 3982 Autowired 3983 类中获取属性数据 40
831 ConfigurationProperties 40832 Value 41
84 Error Handling for REST 4185 Spring boot 自定义注解 41
851 使用自定义注解来统计方法的执行时间 428511 创建 AnalysisActuator 428512 创建 Aspect 428513 使用 43
9 Spring Boot Pages 45
iii
91 理解 Pages 4592 模板引擎 45
921 Jsp 45922 FreeMarker 45923 Groovy 45924 Thymeleaf 46
93 页面获取数据 46931 Model 46932 ModelMap 46933 ModelAndView 47934 ModelAttribute 47
94 webjars 47
10 Spring Boot Entity 49101 概要 49102 Entity 49
1021 Annotation 5010211 Id 5010212 CreatedDate 5110213 Column 5210214 Transient 5210215 Temporal 5210216 Enumerated 53
103 日期处理 531031 配置文件中配置 541032 JsonFormat 541033 DateTimeFormat 541034 Temporal 54
104 Relationship 541041 one-to-one 55
10411 Foreign Key 5510412 Shared Primary Key(推荐) 5910413 Join Table 61
1042 one-to-many 6210421 Unidirectional 6310422 Unidirectional with JoinColumn 6510423 Bidirectional(推荐) 66
1043 many-to-many 69105 H2 69
1051 默认配置 691052 更改 H2 控制台的路径 69
106 初始化数据库数据 70
iv
107 参考 70
11 Spring Data JPA 71111 依赖 71112 创建和删除 JPA 数据库 71113 Query Creation 72114 Using Query 72115 Using Named Parameters 72116 Using SpEL Expressions 73117 Modifying Queries 73118 Init 73119 参考 73
12 Spring Data REST 75121 概要 75122 Maven 依赖 75123 Demo 76124 参考 77
13 Spring Boot Redis 79131 开始使用 Redis 79132 Maven 依赖 79133 Configuration 80134 Demo 80
1341 pom 801342 entity 801343 repository 811344 controller 831345 applicationproperties 84
135 参考 84
14 Spring Boot MongoDB 85141 开始使用 MongoDB 85142 Maven 依赖 85143 CRUD 86
1431 Entity 861432 Repository 861433 Service 871434 RestController 881435 applicationproperties 891436 Mongodb 89
144 参考 90
v
15 Spring Boot Auto-Configuration 91151 理解 auto-configuration 92
1511 学习 auto-configuration 如何工作的 92152 定制 Spring Boot 92
1521 利用 Spring Boot properties 进行定制 921522 替换已生成的 Bean 921523 禁用特定的 auto-configuration 类 921524 修改库的依赖 92
153 基于属性的配置外部化 921531 属性的覆盖(overridden)顺序 921532 重命名 applicationproperties 文件 92
154 外部配置应用程序属性 921541 使用 EnableConfigurationProperties 注解 92
155 基于日志记录的调优 921551 输出日志记录 92
156 使用 YAML 配置文件 921561 YAML 里面的层级属性 921562 单一 YAML 文件中的多个 profiles 属性 92
157 定制应用程序错误页面 92158 小结 92
16 Spring Boot Security 93161 Spring Boot Security 介绍 93
1611 启用 Security 9316111 覆盖默认用户和密码 93
1612 禁用 Security 941613 定制 Security 94
162 OAuth2 Auto-Configuration 95163 JWT 95
1631 JWT 96164 参考 96
17 Spring Boot Actuator 97171 Actuator 介绍 97172 启用 Actuator 97173 Spring Boot 1X 中的 Actuator 98
1731 分析 Actuator 的接口 981732 显示配置细节 981733 利用接口显示指标 991734 显示应用程序信息 991735 关闭应用程序 991736 自定义 Actuator 99
vi
17361 启用或禁用某个 Actuator 接口 10017362 更改接口 ID 10017363 更改 Actuator 接口的灵敏度 10017364 编写自定义健康指标 100
1737 创建一个自定义 Endpoint 1011738 对 Actuator 接口进行安全控制 1021739 Further Customization 103
174 Spring Boot 2X 中的 Actuator 1031741 分析 Actuator 的接口 103
17411 启用或禁用某个 Endpoint 1041742 创建一个自定义 endpoint 1041743 显示 git 详细信息 105
17431 指定 git 地址 10617432 显示全部信息 10617433 关闭 gitproperties 文件的创建 10617434 Verbosity 10617435 过滤敏感信息 107
1744 对 Actuator 接口进行安全控制 107175 spring-boot-admin 107176 参考 107177 小结 108
18 Spring Boot RESTful 109181 基于 Spring Boot 的微服务 109
1811 bootstrapyml 和 applicationyml 简介 1091812 简单的微服务示例 109
182 Spring Data 简介 1091821 Apache Ignite 存储库 1091822 Spring Data MongoDB 1091823 Spring Data JPA 109
183 小结 109
19 Springfox-Swagger2 111191 Maven Dependency 111192 Configuration 111193 Verification 112194 参考 112
20 Spring Cloud 113201 原生云应用程序架构 113
2011 微服务架构 1132012 微服务的优点 1132013 微服务面临的挑战 113
vii
202 简介 1132021 云和微服务程序的构造块 1142022 Spring Cloud 应用 114
203 配置 Spring Cloud 应用程序 114204 小结 116
21 Spring Cloud Config 117211 介绍 117212 配置 Server 117
2121 搭建项目 1172122 创建 Git 存储库 1182123 检验内容 118
213 配置 Client 1182131 搭建项目 1192132 创建客户端属性文件 1202133 检验内容 120
22 Spring Cloud Netflix 121221 Netflix 121222 小结 122
23 Spring Cloud Eureka 123231 服务发现 123232 Eureka 123
2321 Eureka Server 1242322 Eureka Client 126
233 发现 REST 服务 1292331 EurekaClient 1292332 DiscoveryClient 131
234 使用 REST 服务 134235 负载平衡 134236 参考 136
24 Spring Cloud Feign 137241 介绍 137242 依赖 138243 Feign Client 138244 自定义配置 140
2441 自定义 Bean 配置 1412442 使用属性文件配置 1422443 Interceptors 142
245 Feign with Eureka 1432451 Hystrix 145
viii
2452 Logging 1452453 Error 处理 145
246 参考 145
25 Spring Cloud Zuul 147251 Spring Cloud Zuul 147252 参考 147
26 ELK 149261 Elasticsearch 149262 Logstash 149263 Kibana 149264 参考 149
27 Assignment 151271 Maven 151
2711 练习的目标 1512712 练习的要求 151
272 CRUD 1522721 练习的目标 1522722 练习的要求 152
28 Sphinx 155281 Sphinx 155
2811 安装 Sphinx 1552812 搭建 wiki 1552813 主题 155
282 Wiki 语法 1552821 gui 1552822 code 1562823 note 1562824 color 1572825 includefile 1572826 image 1582827 table 1582828 隐藏 source 1602829 link 16028210 Custom CSS 16028211 chapters 16028212 highlight 16028213 脚注 16128214 Error 161
283 部署到 github 161
ix
284 参考 164
29 Spring Cloud Interview 165291 问题集 165
30 Indices and tables 167
x
CHAPTER 1
Spring Boot Cloud 学习
11 课程进度
表 1 课程进度
日期 教学计划 听课人数
2019 年 11 月 8 日 930mdashmdash1130 Spring Boot Entity 12019 年 11 月 12 日 930mdashmdash1130 Spring Boot Entity 22019 年 11 月 15 日 930mdashmdash1130 Spring Data JPA
1
Spring-Cloud Documentation 发布 10
12 练习进度
表 2 学员练习进度
Name Email 项目 Maven CRUD Assign1 Assign2 Assign3 Assign4耿天琦 tqgengcnibmcomSupport 100杨柳 ylwhcnibmcomSupport 100 下一班
吴刚 wuwgcnibmcomHONE 张俊 zjunwhcnibmcomHONE 100 100李海瑛 hyinglicnibmcomHONE 100李凯 whlikaicnibmcomHONE 100林威 whlwcnibmcomHONE 100周慧娟 hjuanzhcnibmcomHONE 徐攀 szpanxucnibmcomHONE 陆挺 lutingwhcnibmcomHONE 曹靖 caojwhcnibmcomSTG 100 100张长松 cszhwhcnibmcomBMT 100 100周振武 zhouzhwucnibmcomLDW 下一班
余鹏 yupcdcnibmcomAstellasPhama
100
朱海林 zhuhlcnibmcomNWAS-STGrt
吴彪 biaowucnibmcomAppOps 曹琳娜 linnacaocnibmcomIOCC 100 100蔡恒 caihengcnibmcomAP fi-
nance100 100
王君 whwjuncnibmcomIGABMT
下一班
柏莉 biaowucnibmcomAIW 100 100王海芳 WHAIFANGcnibmcomGPS
Support-Engage
黄思羽 huangsycnibmcomIOCC 100 100叶飞 feiyecnibmcomds sup-
port100 100
王康 wkangwkcnibmcomSTGElec-tronicCare
2 Chapter 1 Spring Boot Cloud 学习
CHAPTER 2
初识 Maven
21 Maven 介绍
表 1 Maven Lifecycle
phases descriptionvalidate validate the project is correct and all necessary information is avail-
ablecompile compile the source code of the projecttest test the compiled source code using a suitable unit testing framework
These tests should not require the code be packaged or deployedpackage take the compiled code and package it in its distributable format
such as a JARverify run any checks on results of integration tests to ensure quality criteria
are metinstall install the package into the local repository for use as a dependency
in other projects locallydeploy done in the build environment copies the final package to the remote
repository for sharing with other developers and projects
3
Spring-Cloud Documentation 发布 10
22 多线程
mvn -T 4 clean install 用 4 个线程构建mvn -T 1C clean install 根据 CPU 核数每个核分配 1 个线程进行构建
23 跳过测试
-DskipTests 不执行测试用例但编译测试用例类生成相应的 class 文件至 targetrarrtest-classes 下-Dmaventestskip=true 不执行测试用例也不编译测试用例类
24 编译失败后接着编译
mvn -rf moduleName clean install 通过指定之前失败的模块名可以继续之前的编译
25 编译到最后再报错
mvn clean install --fail-at-end 跳过失败的模块编译到最后再报错
26 使用 Nexus 本地私服
27 使用 Aliyun 国内镜像
httpsmavenaliyuncommvnview
ltrepositoriesgtltrepositorygt
ltidgtspring-milestonesltidgtltnamegtSpring Milestonesltnamegtlturlgthttpsrepospringiomilestonelturlgt
ltrepositorygtltrepositoriesgt
4 Chapter 2 初识 Maven
Spring-Cloud Documentation 发布 10
28 指定 Repository 目录
lt-- Default ~m2repository --gtltlocalRepositorygtDappsmavenrepositoryltlocalRepositorygt
29 Maven Properties
mvn clean install -Dmyproperty=propertyValue
210 Maven Sources
mvn dependencysources
211 Maven Proxy
2111 命令行设置
Linux (bash)$ export MAVEN_OPTS=-DsocksProxyHost=10101010 -DsocksProxyPort=8080 Windows$ set MAVEN_OPTS=-DsocksProxyHost=10101010 -DsocksProxyPort=8080
2112 配置文件
$ vim $MAVEN_HOMEconfsettingsxmlltproxiesgt
ltproxygtltidgtsocks-proxyltidgtltactivegttrueltactivegtltprotocolgtsocks5ltprotocolgtlthostgt127001lthostgtltportgt1080ltportgtltnonProxyHostsgtcomltnonProxyHostsgtltproxygt
ltproxiesgt
28 指定 Repository 目录 5
Spring-Cloud Documentation 发布 10
212 Dependency local Jar
1 ltdependencygt2 ltgroupIdgtcomsampleltgroupIdgt3 ltartifactIdgtsampleltartifactIdgt4 ltversiongt10ltversiongt5 ltscopegtsystemltscopegt6 ltsystemPathgt$projectbasedirsrcmainresourcesyourJarjarltsystemPathgt7 ltdependencygt
213 Install Jar
1 mvn installinstall-file -Dfile=RetainSDIjar -DgroupId=comibm -DartifactId=retain -rarrDversion=10 -Dpackaging=jar -DgeneratePom=true
2 mvn deploydeploy-file -DgroupId=richinfo -DartifactId=logscommon -Dversion=001-rarrSNAPSHOT -Dpackaging=jar -Dfile=worktestsftp_testlogscommonjar -Durl=httprarrscmscm1234511235281238815nexuscontentrepositoriessnapshots -rarrDrepositoryId=nexus -s settingsxml
214 MAVEN 属性
2141 内置属性
如 $basedir 表示项目根目录$version 表示项目版本
2142 POM 属性
1 ltprojectgt2 ltmodelVersiongt400ltmodelVersiongt3 ltgroupIdgtorgsonatypemavenbookltgroupIdgt4 ltartifactIdgtproject-altartifactIdgt5 ltversiongt10-SNAPSHOTltversiongt6 ltpackaginggtjarltpackaginggt7 ltbuildgt8 ltfinalNamegt$projectgroupId-$projectartifactIdltfinalNamegt9 ltbuildgt
10 ltprojectgt
6 Chapter 2 初识 Maven
Spring-Cloud Documentation 发布 10
可以使用点标记 () 的路径来引用 POM 元素的值
$basedir 项目根目录$projectbuilddirectory 构建目录缺省为 target$projectbuildoutputDirectory 构建过程输出目录缺省为 targetclasses$projectbuildfinalName 产出物名称缺省为$projectartifactId-$projectversion$projectpackaging 打包类型缺省为 jar$projectxxx 当前 pom 文件的任意节点的内容
2143 自定义属性属性
用户可以在 pom 的 ltpropertiesgt 元素下自定义 maven 属性
2144 setting 属性
用户可以使用以 settings 开头的属性引用 settingsxml 中 xml 元素的值如 $settingslocalRepository 指向用户本地仓库的地址
2145 Java 系统属性
maven 可以使用当前 java 系统的属性如 $userhome 指向了用户目录
2146 环境变量属性
env 变量暴露了你操作系统或者 shell 的环境变量便如在 Maven POM 中一个对 $envPATH 的引用将会被 $PATH 环境变量替换在 Windows 中为PATH所有环境变量都可以使用以 env 开头的属性如$envJAVA_HOE
215 MAVEN_OPTS
MAVEN_OPTS-Xmx1024m
216 Nexus Security
问题描述目前项目组的 Artifact 全部放在云仓库中匿名用户也可以随时访问存在很大的安全问题
bull 解决办法
ndash 统一给仓库添加权限认证阻止匿名用户访问
215 MAVEN_OPTS 7
Spring-Cloud Documentation 发布 10
ndash 选择 Security ndash Users ndash anonymous ndash config ndash status ndash Disabled
bull 执行步骤
ndash 使用项目组统一下发的 settingsxml 文件
bull 参考细节
ndash 本地 mvn 命令加上参数ldquo-s settingsxmlrdquo(如果把 settings 文件替换 mvn 默认的全局文件的话这个可以省略)
ndash wget 命令 1wget ndashauth-no-challenge ndashhttp-user=admin ndashhttp-password=admin123 httpurl
ndash wget 命令 2wget ndashauth-no-challenge ndashuser=admin ndashpassword=admin123 httpurl
ndash curl 命令curl -u adminadmin123 httpurl
217 Error in Eclipse
1 Spring Boot 21X 版本在 Eclipse showing ldquoMaven Configuration Problem Unknownrdquo我们需要在properties 节点中加上 maven-jar-pluginversion
1 ltpropertiesgt2 ltjavaversiongt18ltjavaversiongt3 ltmaven-jar-pluginversiongt311ltmaven-jar-pluginversiongt4 ltpropertiesgt
218 参考
bull httpswwwbaeldungcommaven
bull httpsjazznetdownloadsrational-team-concertreleases6061p=allDownloads
bull 下面 shell 脚本演示的是打印文件夹下文件名的例子
1 binbash2
3 search_dir=UsersmurphyDownloadsRTC-Client-plainJavaLib-60614
5 for entry in `ls $search_dir` do6 echo $entry7 if [ $entry == jar ]8 then9 echo $entry
10 pwd(下页继续)
8 Chapter 2 初识 Maven
Spring-Cloud Documentation 发布 10
(续上页)
11 fi12 done
218 参考 9
Spring-Cloud Documentation 发布 10
10 Chapter 2 初识 Maven
CHAPTER 3
初识 Git
31 常见 Git 命令
克隆和下载项目 git clone httpsgithubcomLiMeiiangular-seed-projectgit提交代码 git push -u origin master git push设置用户名密码 git config ndashglobal username ldquoYour Namerdquo设置用户邮箱 git config ndashglobal useremail youexamplecomSSL Certificate problem unable to get local issuer certificate 解决方案 git config ndashglobal httpsslVerify false查看文件列表 ls查看隐藏文件ls -al查看 Git 状态git status git status -s查看 Git 提交历史git log添加所有改动文件到暂存区(工作区到暂存区)git add 添加某个改动文件到暂存区(工作区到暂存区)git add 文件名提交改动文件到版本库(从暂存区到版本库)git commit -m ldquocommentsrdquo提交改动文件到版本库(直接从工作区到版本库)git commit -a -m ldquocommentsrdquo工作区和暂存区比较git diff工作区和版本库比较git diff 分支名暂存区和版本库比较git diff ndashcached取消本地目录下关联的远程库git remote remove origin撤销所有操作(暂存区覆盖工作区放弃当前工作区修改内容)git checkout
(下页继续)
11
Spring-Cloud Documentation 发布 10
(续上页)
撤销某个文件操作(暂存区覆盖工作区放弃当前工作区修改内容)git checkout 文件名当不小心把当前工作区错误提交到暂存区回滚到上一个暂存区git reset HEAD 文件名查看所有的版本号git reflog按版本号回滚版本git reset ndashhard 版本号回退到上一个版本git reset ndashhard HEAD^回退某一个版本的文件到工作区git checkout 版本号 文件名查看分支git branch创建分支git branch 分支名切换分支git checkout 分支名创建并切换分支git checkout -b 分支名删除分支(需要切换出要删除的分支)git branch -D 分支名暂存更改git stash还原暂存的内容git stash pop合并分支(将指定分支合并到当前所在的分支需要先切换到当前分支比如 master 主分支)gitrarrmerge 指定的分支名把某一个 commit 合并回主分支(需要先切换到主分支)git cherry-pick 99daed2(commitID)推送代码到远程仓库git push origin master推送代码到远程仓库(以后再次提交的时候可以省略地址别名和分支名称直接用命令 git push 进行提交)git push -u origin master拉取最新代码但是不合并代码git fetch origin master拉取最新代码并且合并代码git pull origin master拉取别人的项目到本地git clone 项目地址 项目名初始化 Git 仓库git init查看配置信息git config ndashlist创建文件touch 文件名移动文件mv 文件文件夹 路径查看文件内容cat 文件名删除文件文件夹rm 文件名创建文件夹mkdir 文件夹名查看 URL 地址 git remote -v删除git 文件 find -name ldquogitrdquo | xargs rm -Rfecho tokenmat gtgt gitignore
32 Connecting with SSH
httpshelpgithubcomcnenterprise216userauthenticating-to-githubconnecting-to-github-with-ssh
12 Chapter 3 初识 Git
Spring-Cloud Documentation 发布 10
33 RPC
RPC(remote procedure call)
331 Web
httpsbottlepyorgdocsdevtutorialhtml
import subprocessfrom bottle import run post request response get route abort error
route(ltpathgt method=POST)def process(path)
p = subprocessPopen([python path+py] stdout=subprocessPIPE stderr=subprocessPIPE)
output errors = pcommunicate()if errors
return errorsreturn output
route(ltcommandgtltfilegt method=POST)def processcommand(command file)
p = subprocessPopen([command file] stdout=subprocessPIPE stderr=subprocessPIPE)
output errors = pcommunicate()if errors
return errorsreturn output
route(restricted)def restricted()
abort(401 Sorry access denied)
error(404)def error404(error)
return Nothing here sorry
run(host=localhost port=8080 debug=True)
33 RPC 13
Spring-Cloud Documentation 发布 10
332 SSH
SSH tip Send commands remotely
ssh-keygen -t rsa 生成密钥ssh-copy-id -i ~sshid_rsapub root911198177ssh root911198177 workshellsh
34 API
httpsapigithubcom
14 Chapter 3 初识 Git
CHAPTER 4
初识 Docker
41 介绍
42 Install
421 Centos
httpsdocsdockercominstalllinuxdocker-cecentos
422 Install Docker Compose
httpsdocsdockercomcomposeinstall
43 image and compose
Dockerfile
1 FROM openjdk8-jdk-alpine2 VOLUME tmp3 ARG JAR_FILE4 COPY $JAR_FILE appjar5 ENTRYPOINT [java-jarappjar]
15
Spring-Cloud Documentation 发布 10
docker build ndashbuild-arg JAR_FILE=targetspringbootjar-001-SNAPSHOTjar -t image_name docker run -d ndashname container_name -p 91008080 image_name
注解 -p lthost_portgtltcontainer_portgt
44 command
docker build -t murphylancod_wiki docker push murphylancod_wikidocker run -d --name mshop -p 8080 murphylancod_mshopdocker run -d --name wiki -p 808280 murphylancod_wikidocker ps List all running containersdocker container ls List all running containersdocker container ls -a List all containers even those not runningdocker container stop lthashgt Gracefully stop the specified containerdocker container kill lthashgt Force shutdown of the specified containerdocker container rm lthashgt Remove specified container from this machinedocker container rm $(docker container ls -a -q) Remove all containersdocker image ls -a List all images on this machinedocker image rm ltimage idgt Remove specified image from this machinedocker image rm $(docker image ls -a -q) Remove all images from this machinedocker login Log in this CLI session using your Docker credentialsdocker tag ltimagegt usernamerepositorytag Tag ltimagegt for upload to registrydocker push usernamerepositorytag Upload tagged image to registrydocker run usernamerepositorytag Run image from a registry
docker stack ls List stacks or appsdocker stack deploy -c ltcomposefilegt ltappnamegt Run the specified Compose filedocker service ls List running services associated with an appdocker service ps ltservicegt List tasks associated with an appdocker inspect lttask or containergt Inspect task or containerdocker container ls -q List container IDsdocker stack rm ltappnamegt Tear down an applicationdocker swarm leave --force Take down a single node swarm from the managerdocker logs ltcontainer_idgt 显示日志
16 Chapter 4 初识 Docker
Spring-Cloud Documentation 发布 10
45 搭建 DB server
httpsgithubibmcomlanzejundb-docker
451 docker-composeyml
1 version 32 services3 mysql-server4 container_name mysql-server5 image mysql576 volumes7 - mysqldbvarlibmysql8 environment9 MYSQL_ROOT_PASSWORD mysql123
10 MYSQL_DATABASE my_db11 MYSQL_USER root12 ports13 - 3306330614 expose15 - 330616 mongo-server17 container_name mongo-server18 image mongo408-xenial19 environment20 MONGO_INITDB_ROOT_USERNAME root_app21 MONGO_INITDB_ROOT_PASSWORD root12322 MONGO_DATABASE mymongo23 volumes24 - mongo-initshdocker-entrypoint-initdbdmongo-initshro25 - mongodbdatadbdatadb26 ports27 - 270172701728 expose29 - 2701730 redis31 image bitnamiredis5032 environment33 ALLOW_EMPTY_PASSWORD is recommended only for development34 - ALLOW_EMPTY_PASSWORD=yes
(下页继续)
45 搭建 DB server 17
Spring-Cloud Documentation 发布 10
(续上页)
35 - REDIS_DISABLE_COMMANDS=FLUSHDBFLUSHALL36 ports37 - 6379637938 volumes39 - redisdbbitnamiredisdata40 rabbitmq41 image rabbitmqmanagement42 container_name rabbitmq43 command rabbitmq-server44 ports45 - 156721567246 - 5672567247 expose48 - 567249 - 15672
452 mongo-initsh
1 mongo -- $MONGO_DATABASE ltltEOF2 var user = $MONGO_INITDB_ROOT_USERNAME3 var passwd = $MONGO_INITDB_ROOT_PASSWORD4 var admin = dbgetSiblingDB(admin)5 adminauth(user passwd)6 dbcreateUser(user user pwd passwd roles [readWrite])7 EOF
453 startsh
1 binbash2
3 echo Stop and clean all container 4 docker container rm $(docker container ls -a -q) -f5 docker-compose rm -v6
7 echo Clean all images with sba tag 8 docker rmi $(docker images | grep sba | tr -s | cut -d -f 3)9
10 echo docker-compose build and up (下页继续)
18 Chapter 4 初识 Docker
Spring-Cloud Documentation 发布 10
(续上页)
11 docker-compose build12 docker-compose up -d
46 Issue
bull Cannot connect to the Docker daemon at unixvarrundockersock Is the docker daemon running
systemctl start docker
bull ERROR for user-auth no such image
docker-compose rm -v
bull Delete old Docker images to free up space
remove all unused orphaned imagesecho -e Removing unused imagesdocker rmi -f $(docker images --no-trunc | grep ltnonegt | awk print $3) 2gtamp1rarr| catecho -e Done removing unused images
clean up stuff -gt using these instructions httpslebkowskinamedocker-volumesecho -e Cleaning up old containersdocker ps --filter status=dead --filter status=exited -aq | xargs docker rm -v 2gtamp1rarr| catecho -e Cleaning up old volumesdocker volume ls -qf dangling=true | xargs docker volume rm 2gtamp1 | cat
bull start redis error
1 05500300 INFO ==gt Starting Redis setup 2 05500301 WARN ==gt You set the environment variable ALLOW_EMPTY_PASSWORD=yes For
rarrsafety reasons do not use this flag in a production environment3 05500301 INFO ==gt Initializing Redis4
5 05500308 INFO ==gt Redis setup finished 6 05500309 INFO ==gt Starting Redis 7 1C 01 Nov 2019 055003107 oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo8 1C 01 Nov 2019 055003107 Redis version=505 bits=64 commit=00000000 modified=0
rarr pid=1 just started(下页继续)
46 Issue 19
Spring-Cloud Documentation 发布 10
(续上页)
9 1C 01 Nov 2019 055003107 Configuration loaded10 1M 01 Nov 2019 055003108 Cant open the append-only file Permission denied11 [rootbuildup1 db-docker] sudo chown -R 10011001 redisdb
20 Chapter 4 初识 Docker
CHAPTER 5
Spring Boot CLI
The Spring Boot CLI is a command line tool that you can use if you want to quickly develop a Springapplication
51 安装 Spring Boot CLI
511 从安装文件中手动安装
1 下载安装文件包 lthttpsrepospringioreleaseorgspringframeworkbootspring-boot-cli220RELEASEspring-boot-cli-220RELEASE-binzipgt
2 下载完成后请按照解压缩后的存档中的 INSTALLtxt 说明进行操作
512 使用 SDKMAN 安装
命令如下
$ sdk install springboot$ spring --versionSpring Boot v220RELEASE
21
Spring-Cloud Documentation 发布 10
513 利用 OSX Homebrew 安装
命令如下
$ brew tap pivotaltap$ brew install springboot
514 使用 MacPorts 安装
命令如下
sudo port install spring-boot-cli
52 开始使用 CLI
To verify the install run the command
spring --version
1 创建文件 appgroovy
RestControllerclass ThisWillActuallyRun
RequestMapping()String home()
Hello World
2 然后从 CLI 运行它如下所示
spring run appgroovy
53 使用 CLI 初始化项目
22 Chapter 5 Spring Boot CLI
Spring-Cloud Documentation 发布 10
$ spring init --dependencies=webdata-jpa my-projectUsing service at httpsstartspringioProject extracted to Usersdeveloperexamplemy-project
54 参考
bull httpsdocsspringiospring-bootdocscurrentreferencehtmlspring-boot-clihtml
bull httpsdocsspringiospring-bootdocscurrentreferencehtmlgetting-startedhtmlgetting-started-installing-the-cli
54 参考 23
Spring-Cloud Documentation 发布 10
24 Chapter 5 Spring Boot CLI
CHAPTER 6
Spring Boot 2x 学习
61 Spring Boot 概述
bull 创建独立的 Spring 应用程序
bull 直接嵌入 TomcatJetty 或 Undertow(无需部署 WAR 文件)
bull 提供集成的ldquostarterrdquo依赖项以简化构建配置
bull 尽可能自动配置 Spring 和 3rd Party 库
bull 提供生产就绪的功能例如指标运行状况检查和外部配置
bull 完全没有代码生成也不需要 XML 配置(最低配置或零配置)
bull 约定大于配置
62 常规概念
bull Endpoints
bull Adapter
bull RestFul API
bull Controller + Service + Repository + Entity(3 种状态)
bull Configuration
25
Spring-Cloud Documentation 发布 10
bull Spring Core Spring IOC Spring Boot Spring Data JPA Spring AOP Spring Security Spring Trans-action Spring JDBC Spring MVC Spring Integration and Hibernate ORM
621 PO
persistant object 持久对象
最形象的理解就是一个 PO 就是数据库中的一条记录好处是可以把一条记录作为一个对象处理可以方便的转为其它对象
622 BO
business object 业务对象
主要作用是把业务逻辑封装为一个对象这个对象可以包括一个或多个其它的对象比如一个简历有教育经历工作经历社会关系等等我们可以把教育经历对应一个 PO工作经历对应一个 PO社会关系对应一个 PO
建立一个对应简历的 BO 对象处理简历每个 BO 包含这些 PO这样处理业务逻辑时我们就可以针对BO 去处理
623 VO
value object 值对象 ViewObject 表现层对象
主要对应界面显示的数据对象对于一个 WEB 页面或者 SWTSWING 的一个界面用一个 VO 对象对应整个界面的值
624 POJO
plain ordinary java object 简单 java 对象个人感觉 POJO 是最常见最多变的对象是一个中间对象也是我们最常打交道的对象
bull 一个 POJO 持久化以后就是 PO
bull 直接用它传递传递过程中就是 DTO
bull 直接用来对应表示层就是 VO
625 DTO
Data Transfer Object 数据传输对象主要用于远程调用等需要大量传输对象的地方比如我们一张表有 100个字段那么对应的 PO 就有 100 个属性但是我们界面上只要显示 10 个字段客户端用 WEB service 来获取数据没有必要把整个 PO 对象传递到客户端这时我们就可以用只有这 10 个属性的 DTO 来传递结
26 Chapter 6 Spring Boot 2x 学习
Spring-Cloud Documentation 发布 10
果到客户端这样也不会暴露服务端表结构 到达客户端以后如果用这个对象来对应界面显示那此时它的身份就转为 VO
626 DAO
data access object 数据访问对象这个大家最熟悉和上面几个 O 区别最大基本没有互相转化的可能性和必要 主要用来封装对数据库的访问通过它可以把 POJO 持久化为 PO用 PO 组装出来 VODTO
为什么不能直接用实体模型实现层与层传递
DTO(Data Tansfer Object)即数据传输对象不明白有些框架中为什么要专门定义 DTO 来绑定表现层中的数据为什么不能直接用实体模型实现层与层之间的数据传输有了 DTO 同时还要维护 DTO 与 Model之间的映射关系与转换
表现层与应用层之间是通过数据传输对象(DTO)进行交互的数据传输对象是没有行为的 POJO对象它的目的只是为了对领域对象进行数据封装实现层与层之间的数据传递为何不能直接将领域对象用于数据传递因为领域对象更注重领域而 DTO 更注重数据不仅如此由于ldquo富领域模型rdquo的特点这样做会直接将领域对象的行为暴露给表现层
需要了解的是数据传输对象 DTO本身并不是业务对象数据传输对象是根据 UI的需求进行设计的而不是根据领域对象进行设计的比如Customer 领域对象可能会包含一些诸如 FirstName LastName EmailAddress等信息但如果 UI上不打算显示 Address的信息那么 CustomerDTO中也无需包含这个 Address的数据
简单来说 Model 面向业务我们是通过业务来定义 Model 的而 DTO 是面向界面 UI是通过 UI 的需求来定义的通过 DTO 我们实现了表现层与 Model 之间的解耦表现层不引用 Model如果开发过程中我们的模型改变了而界面没变我们就只需要改 Model 而不需要去改表现层中的东西
63 快速上手
631 在线界面初始化项目
httpsstartspringio
632 环境准备
ensure that you have valid versions of Java and Maven installed
$ java -versionjava version 180_102Java(TM) SE Runtime Environment (build 180_102-b14)Java HotSpot(TM) 64-Bit Server VM (build 25102-b14 mixed mode)
(下页继续)
63 快速上手 27
Spring-Cloud Documentation 发布 10
(续上页)
$ mvn -vApache Maven 354 (1edded0938998edf8bf061f1ceb3cfdeccf443fe 2018-06-rarr17T143314-0400)Maven home usrlocalCellarmaven339libexecJava version 180_102 vendor Oracle Corporation
633 pomxml
Spring Boot provides a number ofldquoStartersrdquothat let you add jars to your classpath The spring-boot-starter-parent is a special starter that provides useful Maven defaults It also provides a dependency-managementsection so that you can omit version tags for ldquoblessedrdquodependencies
Other ldquoStartersrdquoprovide dependencies that you are likely to need when developing a specific type ofapplication Since we are developing a web application we add a spring-boot-starter-web dependencyBefore that we can look at what we currently have by running the following command
mvn dependencytree
The mvn dependencytree command prints a tree representation of your project dependencies
634 添加 Code
打开 Applicationjava 类添加一个方法和一个 annotation(代码高亮部分)
1 package comexampledemo2
3 import orgspringframeworkbootSpringApplication4 import orgspringframeworkbootautoconfigureSpringBootApplication5 import orgspringframeworkwebbindannotationRequestMapping6 import orgspringframeworkwebbindannotationRestController7
8 RestController9 SpringBootApplication
10 public class DemoApplication 11
12 RequestMapping()13 String home() 14 return Hello World15 16
(下页继续)
28 Chapter 6 Spring Boot 2x 学习
Spring-Cloud Documentation 发布 10
(续上页)
17 public static void main(String[] args) 18 SpringApplicationrun(DemoApplicationclass args)19 20
21
1 RestController This annotation provides handling incoming web requests and return JSON response
2 RequestMapping This annotation provides ldquoroutingrdquoinformation
3 main 方法这只是遵循 Java 约定的应用程序入口点的标准方法我们的 main 方法通过调用 run 委托给 Spring Boot 的 SpringApplication 类SpringApplication 会引导我们的应用程序并启动 Spring后者反过来又会启动自动配置的 Tomcat Web 服务器
635 运行程序
介绍 2 种方式运行程序
6351 IDE 中执行
导入到 Eclipse 中然后直接运行 DemoApplication 类中的 main 方法
6352 mvn 执行
在 POM 文件种程序依赖了 spring-boot-starter-parent you have a useful run goal that you can use tostart the application
mvn spring-bootrun
打开浏览器访问 httplocalhost8080 you should see the following output
Hello World
636 创建 an Executable Jar
通过创建可以在生产环境中运行的完全独立的可执行 jar 文件来结束示例可执行 jar(有时称为ldquofat jarrdquo)是包含已编译类以及代码需要运行的所有 jar 依赖项的归档文件
运行命令
mvn package
63 快速上手 29
Spring-Cloud Documentation 发布 10
If you look in the target directory you should see demo-001-SNAPSHOTjar The file should be around 10MB in size If you want to peek inside you can use jar tvf as follows
jar tvf targetdemo-001-SNAPSHOTjar
You should also see a much smaller file named demo-001-SNAPSHOTjaroriginal in the target directoryThis is the original jar file that Maven created before it was repackaged by Spring Boot
To run that application use the java -jar command as follows
java -jar targetdemo-001-SNAPSHOTjar
As before to exit the application press Ctrl + c
637 部署
上述命令一旦关闭命令框程序将会终止这时可以使用如下命令
nohup java -jar your_appjar --serverport=8888 amp
64 参考
httpsdocsspringiospring-bootdocscurrentreferencehtmlgetting-startedhtmlgetting-started-first-application
30 Chapter 6 Spring Boot 2x 学习
CHAPTER 7
Spring Boot Controller
71 理解 Controller
Controller vs RestController
RestController = Controller + ResponseBody
72 实现 REST 服务
1 RestController2 public class HelloWorldController 3 Autowired4 private IHelloWorldService helloWorldService5
6 GetMapping(hello)7 public String hello(String name) 8 return helloWorldServicegetHelloMessage(name)9
10 11
12 Service(下页继续)
31
Spring-Cloud Documentation 发布 10
(续上页)
13 public class HelloWorldServiceImpl implements IHelloWorldService 14
15 public String getHelloMessage(String name) 16 return Hello + OptionalofNullable(name)orElse(World)17 18
19
73 ResponseEntity
httpswwwbaeldungcomspring-response-entity
1 GetMapping(hello)2 ResponseEntityltStringgt hello() 3 return ResponseEntityok(Hello World)4
74 RequestMapping
RequestMapping route 有多种方式
1 package comexampledemocontroller2
3 import orgspringframeworkhttpResponseEntity4 import orgspringframeworkwebbindannotationGetMapping5 import orgspringframeworkwebbindannotationRestController6
7 RestController8 public class HelloController 9
10 GetMapping(hello)11 ResponseEntityltStringgt hello() 12 return ResponseEntityok(Hello World)13 14
15 GetMapping( hello2 hello3 )16 ResponseEntityltStringgt hello2() 17 return ResponseEntityok(Hello World)
(下页继续)
32 Chapter 7 Spring Boot Controller
Spring-Cloud Documentation 发布 10
(续上页)
18 19
20 GetMapping(value = hello3 headers = key=val)21 ResponseEntityltStringgt hello3() 22 return ResponseEntityok(Hello World)23 24
25 GetMapping(value = hello4 headers = key1=val1 key2=val2 )26 ResponseEntityltStringgt hello4() 27 return ResponseEntityok(Hello World)28 29
30 GetMapping(value = hello5 headers = Accept=applicationjson)31 ResponseEntityltStringgt hello5() 32 return ResponseEntityok(Hello World)33 34
35 GetMapping(value = hello6 produces = applicationjson)36 String hello6() 37 return Hello World38 39
40
测试
1 curl -i httplocalhost8080hello2 curl -i -H keyval httplocalhost8080hello33 curl -i -H key1val1 -H key2val2 httplocalhost8080hello44 curl -H Acceptapplicationjsontexthtml httplocalhost8080hello5
75 Controller 中获取参数
751 Controller 方法的形参
直接把表单的参数写在 Controller 相应的方法的形参中适用于 get 方式提交不适用于 post 方式提交
1 2 1 直接把表单的参数写在 Controller 相应的方法的形参中
(下页继续)
75 Controller 中获取参数 33
Spring-Cloud Documentation 发布 10
(续上页)
3 param username4 param password5 return6 7 RequestMapping(addUser1)8 public String addUser1(String usernameString password) 9 Systemoutprintln(username is+username)
10 Systemoutprintln(password is+password)11 return demoindex12
url 形式httplocalhostdemoaddUser1username=trainingamppassword=111111 提交的参数需要和 Con-troller 方法中的入参名称一致
752 HttpServletRequest
通过 HttpServletRequest 接收post 方式和 get 方式都可以
1 2 2通过 HttpServletRequest 接收3 param request4 return5 6 RequestMapping(addUser2)7 public String addUser2(HttpServletRequest request) 8 String username=requestgetParameter(username)9 String password=requestgetParameter(password)
10 Systemoutprintln(username is+username)11 Systemoutprintln(password is+password)12 return demoindex13
753 通过 Bean 接收
通过一个 bean 来接收post 方式和 get 方式都可以
1 2 3通过一个 bean 来接收3 param user
(下页继续)
34 Chapter 7 Spring Boot Controller
Spring-Cloud Documentation 发布 10
(续上页)
4 return5 6 RequestMapping(addUser3)7 public String addUser3(UserModel user) 8 Systemoutprintln(username is+usergetUsername())9 Systemoutprintln(password is+usergetPassword())
10 return demoindex11
754 PathVariable
通过 PathVariable 获取路径中的参数
1 RestController2 RequestMapping(value=users)3 public class MyRestController 4
5 RequestMapping(value=user method=RequestMethodGET)6 public User getUser(PathVariable Long user) 7 8 9
10 RequestMapping(value=usercustomers method=RequestMethodGET)11 ListltCustomergt getUserCustomers(PathVariable Long user) 12 13 14
15 RequestMapping(value=user method=RequestMethodDELETE)16 public User deleteUser(PathVariable Long user) 17 18 19
20
755 ModelAttribute
使用 ModelAttribute 注解获取 POST 请求的 FORM 表单数据
75 Controller 中获取参数 35
Spring-Cloud Documentation 发布 10
1 lt--jsp 页面--gt2 ltform action =lt=requestgetContextPath()gtdemoaddUser5 method=postgt3 用户名ltinput type=text name=usernamegtltbrgt4 密码ltinput type=password name=passwordgtltbrgt5 ltinput type=submit value= 提交gt ltinput type=reset value= 重置gt6 ltformgt
1 2 5使用 ModelAttribute 注解获取 POST 请求的 FORM 表单数据3 param user4 return5 6 RequestMapping(value=addUser5method=RequestMethodPOST)7 public String addUser5(ModelAttribute(user) UserModel user) 8 Systemoutprintln(username is+usergetUsername())9 Systemoutprintln(password is+usergetPassword())
10 return demoindex11
756 RequestParam
用注解 RequestParam 绑定请求参数到方法入参
1 GetMapping(demoid)2 public void demo(PathVariable(name = id) String id RequestParam(name = name)
rarrString name) 3 Systemoutprintln(id=+id)4 Systemoutprintln(name=+name)5
当请求参数 username 不存在时会有异常发生 可以通过设置属性 required=false 解决 例如 Request-Param(value=rdquousernamerdquo required=false)
757 RequestBody
1 PostMapping(path = demo1)2 public void demo1(RequestBody Person person) 3 Systemoutprintln(persontoString())4
36 Chapter 7 Spring Boot Controller
Spring-Cloud Documentation 发布 10
前端 JSON 传值RequestBody 也可以省略
758 RequestHeader CookieValue
1 GetMapping(demo3)2 public void demo3(RequestHeader(name = myHeader) String myHeader3 CookieValue(name = myCookie) String myCookie) 4 Systemoutprintln(myHeader= + myHeader)5 Systemoutprintln(myCookie= + myCookie)6 7
8 9 8上面的代码等同下面的代码
10 11 GetMapping(demo3)12 public void demo3(HttpServletRequest request) 13 Systemoutprintln(requestgetHeader(myHeader))14 for (Cookie cookie requestgetCookies()) 15 if (myCookieequals(cookiegetName())) 16 Systemoutprintln(cookiegetValue())17 18 19
75 Controller 中获取参数 37
Spring-Cloud Documentation 发布 10
38 Chapter 7 Spring Boot Controller
CHAPTER 8
Spring Boot Service
81 理解 Service
Service Components are the class file which contains Service annotation These class files are used to writebusiness logic in a different layer
82 Autowired
Inject list of all beans with a certain interface
1 Component2 public class SomeComponent 3
4 interface SomeInterface 5
6 7
8 Component9 class Impl1 implements SomeInterface
10
11 12
(下页继续)
39
Spring-Cloud Documentation 发布 10
(续上页)
13 Component14 class Impl2 implements SomeInterface 15
16 17
18 Autowired19 private ListltSomeInterfacegt listOfImpls20
83 类中获取属性数据
831 ConfigurationProperties
1 PropertySource(classpathdbconfigproperties)2 ConfigurationProperties(database)3 public class DatabaseConfiguration 4
5 Length(min=2 max=10)6 private String name7
8 NotEmpty9 private String url
10
11 Length(min=5 max=10)12 Pattern(regexp = [a-z-A-Z] message = Username can not contain invalid
rarrcharacters)13 private String username14
15 Length(min=8 max=16)16 private String password17
18
bull PropertySource 标签是指定属性文件默认是 applicationyml 或 applicationproperties
bull ConfigurationProperties 标签指定属性文件中的属性前缀
40 Chapter 8 Spring Boot Service
Spring-Cloud Documentation 发布 10
832 Value
This annotation can be used for injecting values into fields in Spring-managed beans and it can be appliedat the field or constructormethod parameter level
httpswwwbaeldungcomspring-value-annotation
84 Error Handling for REST
ResponseStatus(code = HttpStatusNOT_FOUND reason = Actor Not Found)public class ActorNotFoundException extends Exception
GetMapping(actorid)public String getActorName(PathVariable(id) int id)
try return actorServicegetActor(id)
catch (ActorNotFoundException ex) throw new ResponseStatusException(HttpStatusNOT_FOUND Actor Not Found ex)
bull httpswwwbaeldungcomexception-handling-for-rest-with-spring
bull httpswwwbaeldungcomspring-response-status-exception
bull httpswwwmkyongcomspring-bootspring-rest-error-handling-example
85 Spring boot 自定义注解
1 lt-- AOP 依赖模块 --gt2 ltdependencygt3 ltgroupIdgtorgspringframeworkbootltgroupIdgt4 ltartifactIdgtspring-boot-starter-aopltartifactIdgt5 ltdependencygt
84 Error Handling for REST 41
Spring-Cloud Documentation 发布 10
851 使用自定义注解来统计方法的执行时间
8511 创建 AnalysisActuator
1 package comexampledemoaop2
3 import javalangannotationElementType4 import javalangannotationRetention5 import javalangannotationRetentionPolicy6 import javalangannotationTarget7
8 Target(ElementTypeMETHOD)9 Retention(RetentionPolicyRUNTIME)
10 public interface AnalysisActuator 11 String note() default 12
8512 创建 Aspect
1 package comexampledemoaop2
3 import orgaspectjlangJoinPoint4 import orgaspectjlangannotationAfter5 import orgaspectjlangannotationAspect6 import orgaspectjlangannotationBefore7 import orgaspectjlangannotationPointcut8 import orgslf4jLogger9 import orgslf4jLoggerFactory
10 import orgspringframeworkcoreannotationOrder11 import orgspringframeworkstereotypeComponent12
13 Aspect14 Component15 public class AnalysisActuatorAspect 16 final static Logger log = LoggerFactorygetLogger(AnalysisActuatorAspectclass)17
18 ThreadLocalltLonggt beginTime = new ThreadLocalltgt()19
20 Pointcut(annotation(analysisActuator))21 public void serviceStatistics(AnalysisActuator analysisActuator)
(下页继续)
42 Chapter 8 Spring Boot Service
Spring-Cloud Documentation 发布 10
(续上页)
22 23
24 Before(serviceStatistics(analysisActuator))25 public void doBefore(JoinPoint joinPoint AnalysisActuator analysisActuator) 26 记录请求到达时间27 beginTimeset(SystemcurrentTimeMillis())28 loginfo(------ note analysisActuatornote())29 30
31 After(serviceStatistics(analysisActuator))32 public void doAfter(AnalysisActuator analysisActuator) 33 loginfo(------ statistic time note SystemcurrentTimeMillis() -
rarrbeginTimeget()34 analysisActuatornote())35 36
37
8513 使用
1 package comexampledemocontroller2
3 import javautilOptional4
5 import orgspringframeworkwebbindannotationGetMapping6 import orgspringframeworkwebbindannotationRestController7
8 import comexampledemoaopAnalysisActuator9
10 RestController11 public class HelloWorldController 12
13 GetMapping()14 AnalysisActuator(note = HelloWorldController 中的 hello 方法)15 public String hello(String name) 16 return Hello + OptionalofNullable(name)orElse(World)17 18
调用地址httplocalhost8080name=Java 屏幕打印
85 Spring boot 自定义注解 43
Spring-Cloud Documentation 发布 10
2019-10-22 152118512 INFO 22521 --- [nio-8080-exec-1] cedemoaoprarrAnalysisActuatorAspect
------ noteHelloWorldController 中的 hello 方法2019-10-22 152118550 INFO 22521 --- [nio-8080-exec-1] cedemoaoprarrAnalysisActuatorAspect
------ statistic time38 noteHelloWorldController 中的 hello 方法
44 Chapter 8 Spring Boot Service
CHAPTER 9
Spring Boot Pages
91 理解 Pages
92 模板引擎
921 Jsp
httpswwwbaeldungcomspring-template-engines
1 springmvcviewprefix WEB-INFviews2 springmvcviewsuffix jsp
922 FreeMarker
httpsfreemarkerapacheorg httpshellokodingcomspring-boot-hello-world-example-with-freemarker
923 Groovy
httpswwwbaeldungcomspring-template-engines
45
Spring-Cloud Documentation 发布 10
924 Thymeleaf
httpswwwthymeleaforg httpswwwbaeldungcomspring-boot-crud-thymeleaf
93 页面获取数据
Model ModelMap and ModelAndView are used to define a model in a Spring MVC application
bull Model defines a holder for model attributes and is primarily designed for adding attributes to themodel
bull ModelMap is an extension of Model with the ability to store attributes in a map and chain methodcalls
bull ModelAndView is a holder for a model and a view it allows to return both model and view in onereturn value
931 Model
1 GetMapping()2 public String homePage(Model model) 3 modeladdAttribute(appName appName)4 return home5
页面上
ltspan thtext=$appNamegtOur Appltspangt
932 ModelMap
1 GetMapping(getMessageAndTime)2 public String getMessageAndTime(ModelMap map) 3
4 var ldt = LocalDateTimenow()5
6 var fmt = DateTimeFormatterofLocalizedDateTime(7 FormatStyleMEDIUM)8
9 fmtwithLocale(new Locale(sk SK))10 fmtwithZone(ZoneIdof(CET))
(下页继续)
46 Chapter 9 Spring Boot Pages
Spring-Cloud Documentation 发布 10
(续上页)
11
12 var time = fmtformat(ldt)13
14 mapaddAttribute(message message)addAttribute(time time)15
16 return show17
933 ModelAndView
1 GetMapping(getMessage2)2 public ModelAndView getMessage() 3
4 var mav = new ModelAndView()5
6 mavaddObject(message message)7 mavsetViewName(show)8
9 return mav10
934 ModelAttribute
1 ModelAttribute(motd)2 public String message() 3
4 return messageServicegetMessage()5
94 webjars
bull httpswwwwebjarsorg
bull httpswwwbaeldungcommaven-webjars
94 webjars 47
Spring-Cloud Documentation 发布 10
48 Chapter 9 Spring Boot Pages
CHAPTER 10
Spring Boot Entity
101 概要
JPA 中的实体 (Entity) 就是是 POJO代表可以持久保存到数据库里的数据实体表示存储在数据库中的表实体的每个实例都对应表中的一行
102 Entity
实体 (Entity) 中必须要有一个无参的构造函数和一个主键
Entity(name=Student)Table(name=STUDENT schema=SCHOOL)public class Student
CreatedDateprivate Date creationDate
LastModifiedDateprivate Date modificationDate
Column(name=STUDENT_NAME length=50 nullable=false unique=false)private String name
(下页继续)
49
Spring-Cloud Documentation 发布 10
(续上页)
fields getters and setters
bull Entity 名称默认为类的名称可以使用 name 元素更改其名称name 对应 HQL 里面的查询 Entity
bull Table 名称默认为类的名称可以使用 name 元素更改其名称name 对应 DB 里面的表名
bull 因为各种 JPA 实现都将尝试对我们的 Entity 进行子类化以提供其功能所以不得将 Entity 类声明为final
bull 每个 Entity 都必须具有一个唯一标识它的主键
默认构造函数
如果没有创建构造函数则 Java 编译器将在运行时自动创建无参数构造函数此构造函数称为默认构造函数默认构造函数将初始化所有未初始化的实例变量
1021 Annotation
10211 Id
Entitypublic class User
IdGeneratedValue(strategy = GenerationTypeAUTO)private long id private UUID id
IdGenericGenerator(name = idGenerator strategy = uuid)GeneratedValue(generator = idGenerator)private String id
getters and setters
JPA 自带的几种主键生成策略
1 TABLE使用一个特定的数据库表格来保存主键
50 Chapter 10 Spring Boot Entity
Spring-Cloud Documentation 发布 10
2 SEQUENCE根据底层数据库的序列来生成主键条件是数据库支持序列这个值要与 generator 一起使用generator 指定生成主键使用的生成器(可能是 orcale 中自己编写的序列)
3 IDENTITY主键由数据库自动生成(主要是支持自动增长的数据库如 mysql)
4 AUTO主键由程序控制也是 GenerationType 的默认值
10212 CreatedDate
需要在 Entity 上添加 EntityListeners 标签以及在 Configuration 类上添加 EnableJpaAuditing 标签如下所示
1 Entity(name=Student)2 Table(name=STUDENT schema=SCHOOL)3 EntityListeners(AuditingEntityListenerclass)4 public class Student 5
6 CreatedDate7 private Date creationDate8
9 LastModifiedDate10 private Date modificationDate11
12 Column(name=STUDENT_NAME length=50 nullable=false unique=false)13 private String name14
15 fields getters and setters16
17 18
19 SpringBootApplication20 EnableJpaAuditing21 public class DemoApplication 22
23 public static void main(String[] args) 24 SpringApplicationrun(DemoApplicationclass args)25 26
27
102 Entity 51
Spring-Cloud Documentation 发布 10
10213 Column
1 Entity2 Table(name=STUDENT)3 public class Student 4 Id5 GeneratedValue(strategy=GenerationTypeAUTO)6 private Long id7
8 Column(name=STUDENT_NAME length=50 nullable=false unique=false)9 private String name
10
11 other fields getters and setters12
10214 Transient
有时我们可能希望将字段设为非持久性我们可以使用 Transient 注解它指定该字段将不会持久化到数据库如 Entity 中同时有个出生年月和年龄 2 个字段一般情况下仅需要将出生年月持久化到数据库年龄字段作为逻辑字段不持久化到数据库
10215 Temporal
Temporal 的作用是查询时返回的字段值按照指定日期的格式显示示例
1 Entity2 Table(name=STUDENT)3 public class Student 4 Id5 GeneratedValue(strategy=GenerationTypeAUTO)6 private Long id7
8 Transient9 private Integer age
10
11 Temporal(TemporalTypeDATE)12 private Date birthDate13
14 other fields getters and setters15
52 Chapter 10 Spring Boot Entity
Spring-Cloud Documentation 发布 10
TemporalType 有这么几种值javatimeLocalDate javatimeLocalTime javatimeLocalDateTimejavatimeOffsetTime 和 javatimeOffsetDateTime
1 在该属性上标注 Temporal(TemporalTypeDATE) 会得到形如rsquoyyyy-MM-ddrsquo格式的日期
2 在该属性上标注 Temporal(TemporalTypeTIME) 会得到形如rsquoHHMMSSrsquo格式的日期
3 在该属性上标注 Temporal(TemporalTypeTIMESTAMP) 会得到形如rsquoHHMMSSrsquo格式的日期
10216 Enumerated
1 public enum Gender 2 MALE3 FEMALE4 5
6 Entity7 Table(name=STUDENT)8 public class Student 9 Id
10 GeneratedValue(strategy=GenerationTypeAUTO)11 private Long id12
13 Column(name=STUDENT_NAME length=50 nullable=false unique=false)14 private String name15
16 Transient17 private Integer age18
19 Temporal(TemporalTypeDATE)20 private Date birthDate21
22 Enumerated(EnumTypeSTRING)23 private Gender gender24
25 other fields getters and setters26
103 日期处理
Spring Boot 中未设置日期格式之前前端接收到的时间戳createTime1425300054855
103 日期处理 53
Spring-Cloud Documentation 发布 10
有下面几种方式指定日期格式
1031 配置文件中配置
springjacksondate-format = yyyy-MM-dd HHmmss
1032 JsonFormat
1 JsonFormat(pattern=yyyy-MM-dd HHmm)2 private Date createTime
1033 DateTimeFormat
1 DateTimeFormat(pattern = yyyy-MM-dd)2 private Date createTime
DateTimeFormat 格式化日期需要注意的是使用时要引入一个类库 joda-time-13jar否则会无法访问相应路径 (400 错误)
1034 Temporal
详细内容参照上面的 Temporal 讲解部分
104 Relationship
JPA 关系可以是单向或双向的这只是意味着我们可以将它们的关系建模在实体属性的一方或者双方主要区别在于双向关系提供了双向导航访问因此您无需显式查询即可访问另一侧此外它还允许您在两个方向上应用级联选项定义实体之间关系的方向不会影响数据库映射它仅定义了在域模型中使用该关系的方向节省了维护代码的成本
模型关系的定义可能会迫使数据库创建除表之外的其他资源如索引触发器等
bull JoinColumn 注解指定用于连接关联的实体或元素的集合它声明在 Owner 方
bull mappedBy 属性用于定义关系维护的 refering 方(non-owning side)
bull mappedBy 与 JoinColumn 和 JoinTable 互斥不能同时作用于同一个属性上
54 Chapter 10 Spring Boot Entity
Spring-Cloud Documentation 发布 10
1041 one-to-one
本文将介绍 3 种方式描述 JPA 的一对一(OneToOne)关系
1 在单向 (unidirectional) 映射中拥有方的表结构必须包含一个 JoinColumn 列该 JoinColumn 列引用另一个表的 ID
2 在双向 (bidirectional) 映射中Owner 和非 Owner 都必须有 OneToOne 注解其中非 Owner 实体必须包含 mappedBy 属性
10411 Foreign Key
这是 2 个表的 ER 图
User 表中有个外键字段ldquoaddress_idrdquo它的值指向的是 address 表中的主键ldquoidrdquo
Unidirectional
Unidirectional 简单的讲就是讲关系配置在 Owner 方
列表 1 Userjava
1 Entity2 Table(name = users)3 public class User 4
5 Id6 GeneratedValue(strategy = GenerationTypeAUTO)7 Column(name = id)8 private Long id9
10
11 OneToOne(cascade = CascadeTypeALL)12 JoinColumn(name = address_id referencedColumnName = id)13 private Address address14
(下页继续)
104 Relationship 55
Spring-Cloud Documentation 发布 10
(续上页)
15 getters and setters16
列表 2 Addressjava
1 Entity2 Table(name = address)3 public class Address 4
5 Id6 GeneratedValue(strategy = GenerationTypeAUTO)7 Column(name = id)8 private Long id9
10
11 getters and setters12
Bidirectional
Bidirectional 关系需要双方都要配置这里在 Unidirectional 的基础上需要另外在非 Owner 端添加 One-ToOne 注解
列表 3 Addressjava
1 Entity2 Table(name = address)3 public class Address 4
5 Id6 GeneratedValue(strategy = GenerationTypeAUTO)7 Column(name = id)8 private Long id9
10
11 OneToOne(mappedBy = address)12 private User user13
14 getters and setters15
56 Chapter 10 Spring Boot Entity
Spring-Cloud Documentation 发布 10
请注意
1 JoinColumn 注解在 User 端表示 User 是 Owner 端
2 JoinColumn 注解中 name 属性用于定义外键的名称这里表示 User 表中有个列名为ldquoaddress_idrdquo如果我们不提供名称那么 Hibernate 将遵循一些 规则 来选择默认名称referencedColumnName =ldquoidrdquo指示它映射到 Address 表中的主键ldquoidrdquo默认是主键因此 referencedColumnName 可以省略
3 cascade=CascadeTypeALL 表示级联维护关系如当删除 user会级联删除 address
4 在实践中mappedBy 属性很重要如果不配置(如仅配置 OneToOne)创建表时会在 Address表中额外添加rdquouser_idldquo字段同时 2 个实体的关系依然为 Unidirectional
CRUD 操作
1 Repository2 public interface UserRepository extends JpaRepositoryltUser Longgt 3
4 public User findByName(String name)5
6 7
8
9 package comexampledemoinit10
11 import static orgjunitAssertassertEquals12
13 import javaxannotationPostConstruct14
15 import orgslf4jLogger16 import orgslf4jLoggerFactory17 import orgspringframeworkbeansfactoryannotationAutowired18 import orgspringframeworkstereotypeComponent19
20 import comexampledemoentityAddress21 import comexampledemoentityUser22 import comexampledemorepositoryAddressRepository23 import comexampledemorepositoryUserRepository24
25 Component26 public class PostConstructExampleBean 27 private static final Logger logger = LoggerFactory
rarrgetLogger(PostConstructExampleBeanclass)(下页继续)
104 Relationship 57
Spring-Cloud Documentation 发布 10
(续上页)
28
29 Autowired30 private UserRepository userRepository31 Autowired32 private AddressRepository addressRepository33
34 PostConstruct35 public void init() 36 loggerinfo(init)37
38 given39 User user1 = new User()40 user1setName(user1)41 userRepositorysave(user1)42
43 User user2 = new User()44 user2setName(user2)45 Address address = new Address()46 addresssetStreet(Soft City No1)47 user2setAddress(address)48
49 userRepositorysave(user2)50
51 查询 user152 User found1 = userRepositoryfindByName(user1getName())53 assertEquals(found1getName() user1getName())54
55 查询 user2 然后获得它的关联实体56 User found2 = userRepositoryfindByName(user2getName())57 assertEquals(found2getAddress()getStreet() addressgetStreet())58
59 查询 Address 然后获得它的关联实体60 Address found3 = addressRepositoryfindByStreet(addressgetStreet())61 assertEquals(found3getUser()getName() user2getName())62
63 loggerinfo(initover)64 65
请注意
58 Chapter 10 Spring Boot Entity
Spring-Cloud Documentation 发布 10
bull Unidirectional 与 Bidirectional 的区别就是查询的方向Unidirectional 只能是 Owner 到非 Owner 端查询Bidirectional 是双向可以查询
bull 无论是 Unidirectional 还是 Bidirectional创建的表结构是相同的
10412 Shared Primary Key(推荐)
在此例中我们将创建 Address 表的主键列(user_id)作为 User 表的外键而不是创建新的列 address_id
此方案利用这些实体之间存在一对一的关系优化了表的存储空间
列表 4 Userjava
1 Entity2 Table(name = users)3 public class User 4
5 Id6 GeneratedValue(strategy = GenerationTypeAUTO)7 Column(name = id)8 private Long id9
10 11
12 OneToOne(mappedBy = user cascade = CascadeTypeALL)13 private Address address14
15 getters and setters16
列表 5 Addressjava
1 Entity2 Table(name = address)3 public class Address 4
(下页继续)
104 Relationship 59
Spring-Cloud Documentation 发布 10
(续上页)
5 Id6 Column(name = id)7 private Long id8
9 10
11 OneToOne12 MapsId13 private User user14
15 getters and setters16
1 MapsId 表示使用列 id 同时作为 Address 表的主键和外键这里 Address 表的主键 id 不再是 Gen-eratedValue 声明了
2 按照上一节讲的mappedBy 属性定义在非 Owner 方因此这里的 Owner 方变为 Address 实体了因此save 操作的级联维护关系需要从 Address 实体方向开始
CRUD 操作
1 PostConstruct2 public void init2() 3 loggerinfo(init2)4
5 given6 User user1 = new User()7 user1setName(user1)8 userRepositorysave(user1)9
10 User user2 = new User()11 user2setName(user2)12 Address address = new Address()13 addresssetStreet(Soft City No1)14 addresssetUser(user2)15
16 addressRepositorysave(address)17
18 查询 user119 User found1 = userRepositoryfindByName(user1getName())
(下页继续)
60 Chapter 10 Spring Boot Entity
Spring-Cloud Documentation 发布 10
(续上页)
20 assertEquals(found1getName() user1getName())21
22 查询 user2 然后获得它的关联实体23 User found2 = userRepositoryfindByName(user2getName())24 assertEquals(found2getAddress()getStreet() addressgetStreet())25
26 查询 Address 然后获得它的关联实体27 Address found3 = addressRepositoryfindByStreet(addressgetStreet())28 assertEquals(found3getUser()getName() user2getName())29
30 loggerinfo(init2over)31
10413 Join Table
到目前为止我们已经讨论过的策略允许空值存在使用联接表可以帮助我们消除这些空值
列表 6 Employeejava
1 Entity2 Table(name = employee)3 public class Employee 4 Id5 GeneratedValue(strategy = GenerationTypeAUTO)6 Column(name = id)7 private Long id8
9 10
11 OneToOne(cascade = CascadeTypeALL)12 JoinTable(name = emp_workstation13 joinColumns =14 JoinColumn(name = employee_id referencedColumnName = id)
(下页继续)
104 Relationship 61
Spring-Cloud Documentation 发布 10
(续上页)
15 inverseJoinColumns =16 JoinColumn(name = workstation_id referencedColumnName = id) )17 private WorkStation workStation18
19 getters and setters20
列表 7 WorkStationjava
1 Entity2 Table(name = workstation)3 public class WorkStation 4
5 Id6 GeneratedValue(strategy = GenerationTypeAUTO)7 Column(name = id)8 private Long id9
10 11
12 OneToOne(mappedBy = workStation)13 private Employee employee14
15 getters and setters16
1 Employee is the owner of this relationship as we chose to use the JoinTable annotation on it
2 如果不需要根据 WorkStation 级联查询 Employee可以注释掉 WorkStation 类中的ldquoemployeerdquo字段(包括 OneToOne 注解)
1042 one-to-many
JPA使用 OneToMany和 ManyToOne来标识一对多的双向关联一端 (Author)使用 OneToMany多端 (Article) 使用 ManyToOne
在 JPA 规范中一对多的双向关系由多端 (Article) 来维护就是说多端 (Article) 为关系 维护端负责关系的增删改查一端 (Author) 则为关系 被维护端不能维护关系
62 Chapter 10 Spring Boot Entity
Spring-Cloud Documentation 发布 10
列表 8 Authorjava
1 Entity2 public class Author 3 Id 主键4 GeneratedValue(strategy = GenerationTypeIDENTITY) 自增长策略5 private Long id id6
7 private String name姓名8
9 OneToMany(mappedBy = authorcascade=CascadeTypeALLfetch=FetchTypeLAZY)10 级联保存更新删除刷新 延迟加载当删除用户会级联删除该用户的所有文章11 拥有 mappedBy 注解的实体类为关系被维护端12 mappedBy=author 中的 author 是 Article 中的 author 属性13 private ListltArticlegt articleList文章列表14
列表 9 Articlejava
1 Entity2 public class Article 3 Id4 GeneratedValue(strategy = GenerationTypeIDENTITY) 自增长策略5 Column(name = id nullable = false)6 private Long id7
8 private String title9
10 可选属性 optional=false 表示 author 不能为空删除文章不影响用户11 ManyToOne(cascade=CascadeTypeMERGECascadeTypeREFRESHoptional=false)12 JoinColumn(name=author_id)设置在 article 表中的关联字段 (外键)13 private Author author所属作者14
10421 Unidirectional
1 Entity(name = Post)2 Table(name = post)3 public class Post
(下页继续)
104 Relationship 63
Spring-Cloud Documentation 发布 10
(续上页)
4
5 Id6 GeneratedValue7 private Long id8
9 private String title10
11 OneToMany(cascade = CascadeTypeALL orphanRemoval = true)12 private ListltPostCommentgt comments = new ArrayListltgt()13
14 Constructors getters and setters removed for brevity15 16
17 Entity(name = PostComment)18 Table(name = post_comment)19 public class PostComment 20
21 Id22 GeneratedValue23 private Long id24
25 private String review26
27 Constructors getters and setters removed for brevity28
现在我们尝试创建 1 条 Post 和 3 条 PostComment 记录
1 Post post = new Post(First post)2
3 postgetComments()add(4 new PostComment(My first review)5 )6 postgetComments()add(7 new PostComment(My second review)8 )9 postgetComments()add(
10 new PostComment(My third review)11 )12
(下页继续)
64 Chapter 10 Spring Boot Entity
Spring-Cloud Documentation 发布 10
(续上页)
13 entityManagerpersist(post)
底层的 Hibernate 将会执行下面的 SQL
1 insert into post (title id) values (First post 1)2 insert into post_comment (review id) values (My first review 2)3 insert into post_comment (review id) values (My second review 3)4 insert into post_comment (review id) values (My third review 4)5 insert into post_post_comment (Post_id comments_id) values (1 2)6 insert into post_post_comment (Post_id comments_id) values (1 3)7 insert into post_post_comment (Post_id comments_id) values (1 4)
从上面的 SQL 语句看将会创建 3 张表类似下图所示
对于 DBA这看起来更像是多对多数据库关联而不是一对多关系而且效率也不高现在有了三个表而不是两个表因此使用了不必要的存储空间现在多了两个外键有可能对这些外键建立索引因此将需要两倍的内存来缓存此关联的索引此方案不是很好
10422 Unidirectional with JoinColumn
要解决上述额外的联接表问题只需要添加 JoinColumn
1 OneToMany(cascade = CascadeTypeALL orphanRemoval = true)2 JoinColumn(name = post_id)3 private ListltPostCommentgt comments = new ArrayListltgt()
有了此注释持久化 1 个 Post 和 3 个 PostComment 实体时将获得以下 SQL 输出
1 insert into post (title id) values (First post 1)2 insert into post_comment (review id) values (My first review 2)3 insert into post_comment (review id) values (My second review 3)4 insert into post_comment (review id) values (My third review 4)5 update post_comment set post_id = 1 where id = 26 update post_comment set post_id = 1 where id = 37 update post_comment set post_id = 1 where id = 4
104 Relationship 65
Spring-Cloud Documentation 发布 10
好一点了但是多了三个更新语句
If you take a look at Hibernate flush order yoursquoll see that the persist action is executed before the collectionelements are handled This way Hibernate inserts the child records first without the Foreign Key since thechild entity does not store this information During the collection handling phase the Foreign Key columnis updated accordingly
The same logic applies to collection state modifications so when removing the firsts entry from the childcollection
1 postgetComments()remove(0)
Hibernate executes two statements instead of one
1 update post_comment set post_id = null where post_id = 1 and id = 22 delete from post_comment where id=2
Again the parent entity state change is executed first which triggers the child entity update Afterwardwhen the collection is processed the orphan removal action will execute the child row delete statement
10423 Bidirectional(推荐)
The best way to map a OneToMany association is to rely on the ManyToOne side to propagate all entitystate changes
1 Entity(name = Post)2 Table(name = post)3 public class Post 4
5 Id6 GeneratedValue7 private Long id8
9 private String title10
11 OneToMany(12 mappedBy = post13 cascade = CascadeTypeALL14 orphanRemoval = true15 )16 private ListltPostCommentgt comments = new ArrayListltgt()17
18 Constructors getters and setters removed for brevity(下页继续)
66 Chapter 10 Spring Boot Entity
Spring-Cloud Documentation 发布 10
(续上页)
19
20 public void addComment(PostComment comment) 21 commentsadd(comment)22 commentsetPost(this)23 24
25 public void removeComment(PostComment comment) 26 commentsremove(comment)27 commentsetPost(null)28 29 30
31 Entity(name = PostComment)32 Table(name = post_comment)33 public class PostComment 34
35 Id36 GeneratedValue37 private Long id38
39 private String review40
41 ManyToOne(fetch = FetchTypeLAZY)42 JoinColumn(name = post_id)43 private Post post44
45 Constructors getters and setters removed for brevity46
47 Override48 public boolean equals(Object o) 49 if (this == o) return true50 if ((o instanceof PostComment )) return false51 return id = null ampamp idequals(((PostComment) o)getId())52 53 Override54 public int hashCode() 55 return 3156 57
There are several things to note on the aforementioned mapping
104 Relationship 67
Spring-Cloud Documentation 发布 10
1 The ManyToOne association uses FetchTypeLAZY because otherwise wersquod fall back to EAGERfetching which is bad for performance
2 The parent entity Post features two utility methods (eg addComment and removeComment) whichare used to synchronize both sides of the bidirectional association You should always provide thesemethods whenever you are working with a bidirectional association as otherwise you risk very subtlestate propagation issues
3 The child entity PostComment implement the equals and hashCode methods Since we cannot relyon a natural identifier for equality checks we need to use the entity identifier instead However youneed to do it properly so that equality is consistent across all entity state transitions Because we relyon equality for the removeComment itrsquos good practice to override equals and hashCode for the childentity in a bidirectional association
If we persist three PostComment(s)
1 Post post = new Post(First post)2
3 postaddComment(4 new PostComment(My first review)5 )6 postaddComment(7 new PostComment(My second review)8 )9 postaddComment(
10 new PostComment(My third review)11 )12
13 entityManagerpersist(post)
Hibernate generates just one SQL statement for each persisted PostComment entity
1 insert into post (title id) values (First post 1)2 insert into post_comment (post_id review id) values (1 My first review 2)3 insert into post_comment (post_id review id) values (1 My second review 3)4 insert into post_comment (post_id review id) values (1 My third review 4)
If we remove a PostComment
1 Post post = entityManagerfind( Postclass 1L )2 PostComment comment1 = postgetComments()get( 0 )3
4 postremoveComment(comment1)
Therersquos only one delete SQL statement that gets executed
68 Chapter 10 Spring Boot Entity
Spring-Cloud Documentation 发布 10
1 delete from post_comment where id = 2
So the bidirectional OneToMany association is the best way to map a one-to-many database relationshipwhen we really need the collection on the parent side of the association
1043 many-to-many
类似上面的 3 表关联
105 H2
1 ltdependencygt2 ltgroupIdgtcomh2databaseltgroupIdgt3 ltartifactIdgth2ltartifactIdgt4 ltdependencygt
1051 默认配置
启动 Spring Boot 时控制台显示
H2 console available at h2-console Database available at jdbch2memtestdb
Spring Boot 默认的完整 H2 配置如下
springdatasourceurl=jdbch2memtestdbspringdatasourcedriverClassName=orgh2Driverspringdatasourceusername=saspringdatasourcepassword=passwordspringjpadatabase-platform=orghibernatedialectH2Dialect
1052 更改 H2 控制台的路径
可以通过 springh2consoleenabled 来禁用 H2 控制台
springh2consoleenabled=false
默认情况下控制台位于h2-console您可以使用 springh2consolepath 属性自定义控制台的路径
可以设置一个固定路径通过指定 springdatasourceurl 属性
105 H2 69
Spring-Cloud Documentation 发布 10
springdatasourceurl=jdbch2filedatademo
106 初始化数据库数据
add a datasql file in srcmainresources
1 DROP TABLE IF EXISTS billionaires2
3 CREATE TABLE billionaires (4 id INT AUTO_INCREMENT PRIMARY KEY5 first_name VARCHAR(250) NOT NULL6 last_name VARCHAR(250) NOT NULL7 career VARCHAR(250) DEFAULT NULL8 )9
10 INSERT INTO billionaires (first_name last_name career) VALUES11 (Aliko Dangote Billionaire Industrialist)12 (Bill Gates Billionaire Tech Entrepreneur)13 (Folrunsho Alakija Billionaire Oil Magnate)
107 参考
bull httpswwwbaeldungcomjpa-one-to-one
bull httpsvladmihalceacomthe-best-way-to-map-a-onetomany-association-with-jpa-and-hibernate
70 Chapter 10 Spring Boot Entity
CHAPTER 11
Spring Data JPA
Spring Data JPA 旨在通过减少实际需要的工作量来显著改善数据访问层的实现作为开发人员仅需编写repository 接口包括自定义查找器方法Spring 将自动提供实现
111 依赖
1 ltdependencygt2 ltgroupIdgtorgspringframeworkbootltgroupIdgt3 ltartifactIdgtspring-boot-starter-data-jpaltartifactIdgt4 ltdependencygt
112 创建和删除 JPA 数据库
默认情况下仅当您使用嵌入式数据库(H2HSQL 或 Derby)时才会自动创建 JPA 数据库您可以使用springjpa 属性显式配置 JPA 设置例如要创建和删除表可以将以下行添加到 applicationproperties
springjpahibernateddl-auto=create-drop
值可以是这些
bull create每次运行程序时都会重新创建表故而数据会丢失
bull create-drop每次运行程序时会先创建表结构然后待程序结束时清空表
71
Spring-Cloud Documentation 发布 10
bull upadte每次运行程序没有表时会创建表如果对象发生改变会更新表结构原有数据不会清空只会更新(推荐使用)
bull validate运行程序会校验数据与数据库的字段类型是否相同字段不同会报错
bull none 禁用 DDL 处理
113 Query Creation
public interface UserRepository extends RepositoryltUser Longgt ListltUsergt findByEmailAddressAndLastname(String emailAddress String lastname)
httpsdocsspringiospring-datajpadocs220RELEASEreferencehtmljpaquery-methodsquery-creation
114 Using Query
public interface UserRepository extends JpaRepositoryltUser Longgt Query(select u from User u where uemailAddress = 1)User findByEmailAddress(String emailAddress)
httpsdocsspringiospring-datajpadocs220RELEASEreferencehtmljpaquery-methodsat-query
115 Using Named Parameters
public interface UserRepository extends JpaRepositoryltUser Longgt
Query(select u from User u where ufirstname = firstname or ulastname = lastname)User findByLastnameOrFirstname(Param(lastname) String lastname
Param(firstname) String firstname)
72 Chapter 11 Spring Data JPA
Spring-Cloud Documentation 发布 10
116 Using SpEL Expressions
Entitypublic class User
IdGeneratedValueLong id
String lastname
public interface UserRepository extends JpaRepositoryltUserLonggt
Query(select u from entityName u where ulastname = 1)ListltUsergt findByLastname(String lastname)
httpsdocsspringiospring-datajpadocs220RELEASEreferencehtmljpaqueryspel-expressions
117 Modifying Queries
ModifyingQuery(update User u set ufirstname = 1 where ulastname = 2)int setFixedFirstnameFor(String firstname String lastname)
httpsdocsspringiospring-datajpadocs220RELEASEreferencehtmljpamodifying-queries
118 Init
httpswwwbaeldungcomrunning-setup-logic-on-startup-in-spring
119 参考
httpsdocsspringiospring-datajpadocs220RELEASEreferencehtmlreference
116 Using SpEL Expressions 73
Spring-Cloud Documentation 发布 10
74 Chapter 11 Spring Data JPA
CHAPTER 12
Spring Data REST
121 概要
本文将解释 Spring Data REST的基础知识并展示如何使用它来构建简单的 REST API通常Spring DataREST是在 Spring Data项目的基础上构建的可轻松构建连接到 Spring Data存储库的 hypermedia-driven的 REST Web 服务-所有这些都使用 HAL 作为驱动超媒体类型
它减少了通常与此类任务相关的大量手动工作并使 Web 应用程序的基本 CRUD 功能实现变得非常简单
在本文中我们将研究如何在 Spring Data REST 中处理实体之间的关系我们将重点研究 Spring DataREST 为存储库提供的关联资源同时考虑可以定义的每种关系类型为了避免任何额外的设置我们将使用 H2 嵌入式数据库作为示例
122 Maven 依赖
1 ltdependencygt2 ltgroupIdgtorgspringframeworkbootltgroupIdgt3 ltartifactIdgtspring-boot-starter-webltartifactIdgt4 ltdependencygt5 ltdependencygt6 ltgroupIdgtorgspringframeworkbootltgroupIdgt7 ltartifactIdgtspring-boot-starter-data-restltartifactIdgt8 ltdependencygt
(下页继续)
75
Spring-Cloud Documentation 发布 10
(续上页)
9 ltdependencygt10 ltgroupIdgtorgspringframeworkbootltgroupIdgt11 ltartifactIdgtspring-boot-starter-data-jpaltartifactIdgt12 ltdependencygt13 ltdependencygt14 ltgroupIdgtcomh2databaseltgroupIdgt15 ltartifactIdgth2ltartifactIdgt16 ltdependencygt
123 Demo
1 创建 Entity
1 package comexamplerestentity2
3 import javaxpersistenceEntity4 import javaxpersistenceGeneratedValue5 import javaxpersistenceGenerationType6 import javaxpersistenceId7
8 Entity9 public class WebsiteUser
10
11 Id12 GeneratedValue(strategy = GenerationTypeAUTO)13 private long id14
15 private String name16 private String email17
18 standard getters and setters19
20
2 创建 Entity
1 package comexamplerestrepository2
3 import javautilList(下页继续)
76 Chapter 12 Spring Data REST
Spring-Cloud Documentation 发布 10
(续上页)
4
5 import orgspringframeworkdatarepositoryPagingAndSortingRepository6 import orgspringframeworkdatarepositoryqueryParam7 import orgspringframeworkdatarestcoreannotationRepositoryRestResource8
9 import comexamplerestentityWebsiteUser10
11 RepositoryRestResource(collectionResourceRel = users path = users)12 public interface UserRepository extends PagingAndSortingRepositoryltWebsiteUser Longgt 13 ListltWebsiteUsergt findByName(Param(name) String name)14
3 增加 user
1 curl -i -X POST -H Content-Typeapplicationjson -d name Test email rarrtesttestcom httplocalhost8080users
4 访问 httplocalhost8080users1
1 2 name Test3 email testtestcom4 _links 5 self 6 href httplocalhost8080users17 8 websiteUser 9 href httplocalhost8080users1
10 11 12
5 查询 httplocalhost8080userssearchfindByNamename=Test
124 参考
bull httpswwwbaeldungcomspring-data-rest-intro
bull httpswwwbaeldungcomspring-data-rest-relationships
124 参考 77
Spring-Cloud Documentation 发布 10
78 Chapter 12 Spring Data REST
CHAPTER 13
Spring Boot Redis
131 开始使用 Redis
132 Maven 依赖
1 ltdependencygt2 ltgroupIdgtorgspringframeworkdataltgroupIdgt3 ltartifactIdgtspring-data-redisltartifactIdgt4 ltversiongt203RELEASEltversiongt5 ltdependencygt6
7 ltdependencygt8 ltgroupIdgtredisclientsltgroupIdgt9 ltartifactIdgtjedisltartifactIdgt
10 ltversiongt290ltversiongt11 lttypegtjarlttypegt12 ltdependencygt
79
Spring-Cloud Documentation 发布 10
133 Configuration
1 Bean2 JedisConnectionFactory jedisConnectionFactory() 3 JedisConnectionFactory jedisConFactory4 = new JedisConnectionFactory()5 jedisConFactorysetHostName(localhost)6 jedisConFactorysetPort(6379)7 return jedisConFactory8 9
10 Bean11 public RedisTemplateltString Objectgt redisTemplate() 12 RedisTemplateltString Objectgt template = new RedisTemplateltgt()13 templatesetConnectionFactory(jedisConnectionFactory())14 return template15
134 Demo
1341 pom
1 ltdependencygt2 ltgroupIdgtorgspringframeworkbootltgroupIdgt3 ltartifactIdgtspring-boot-starter-webltartifactIdgt4 ltdependencygt5 ltdependencygt6 ltgroupIdgtorgspringframeworkbootltgroupIdgt7 ltartifactIdgtspring-boot-starter-data-redisltartifactIdgt8 ltdependencygt
1342 entity
1 package comexampleredisentity2
3 public class User 4
(下页继续)
80 Chapter 13 Spring Boot Redis
Spring-Cloud Documentation 发布 10
(续上页)
5 private String id6 private String name7 private long followers8
9 public String getId() 10 return id11 12
13 public void setId(String id) 14 thisid = id15 16
17 public String getName() 18 return name19 20
21 public void setName(String name) 22 thisname = name23 24
25 public long getFollowers() 26 return followers27 28
29 public void setFollowers(long followers) 30 thisfollowers = followers31 32
33 Override34 public String toString() 35 return User [id= + id + name= + name + followers= + followers + ]36 37
38
1343 repository
1 package comexampleredisrepository2
(下页继续)
134 Demo 81
Spring-Cloud Documentation 发布 10
(续上页)
3 import javautilMap4
5 import javaxannotationPostConstruct6
7 import orgspringframeworkbeansfactoryannotationAutowired8 import orgspringframeworkdataredisconnectionlettuceLettuceConnectionFactory9 import orgspringframeworkdatarediscoreHashOperations
10 import orgspringframeworkdatarediscoreStringRedisTemplate11 import orgspringframeworkstereotypeRepository12
13 import comexampleredisentityUser14
15 Repository16 public class UserRepository 17
18 Autowired19 private StringRedisTemplate stringRedisTemplate20
21 private HashOperationsltString Object Objectgt hashOperations22
23 PostConstruct24 private void init() 25 hashOperations = stringRedisTemplateopsForHash()26 27
28 public void setDatabase(int index) 29 LettuceConnectionFactory lettuceConnectionFactory = (LettuceConnectionFactory)
rarrstringRedisTemplate30 getConnectionFactory()31 lettuceConnectionFactorygetStandaloneConfiguration()setDatabase(index)32 stringRedisTemplatesetConnectionFactory(lettuceConnectionFactory)33 34
35 public void save(User user) 36 setDatabase(0)37 hashOperationsput(USER usergetId() usertoString())38 39
40 public void delete(String id) 41 hashOperationsdelete(USER id)
(下页继续)
82 Chapter 13 Spring Boot Redis
Spring-Cloud Documentation 发布 10
(续上页)
42 43
44 public Map getUsers() 45 return hashOperationsentries(USER)46 47
48
1344 controller
1 package comexamplerediscontroller2
3 import javatimeLocalTime4 import javautilMap5
6 import orgspringframeworkbeansfactoryannotationAutowired7 import orgspringframeworkhttpResponseEntity8 import orgspringframeworkwebbindannotationGetMapping9 import orgspringframeworkwebbindannotationRestController
10
11 import comexampleredisentityUser12 import comexampleredisrepositoryUserRepository13
14 RestController15 public class HelloWorldController 16 Autowired17 private UserRepository userRepository18
19 GetMapping()20 public ResponseEntityltMapgt hello(String name) 21 User user = new User()22 usersetId(LocalTimenow()toString())23 usersetName(Murphy)24 usersetFollowers(33)25 userRepositorysave(user)26
27 return ResponseEntityok(userRepositorygetUsers())28 29
134 Demo 83
Spring-Cloud Documentation 发布 10
1345 applicationproperties
springredishost=127001springredisport=6379
135 参考
httpswwwbaeldungcomspring-data-redis-tutorial
84 Chapter 13 Spring Boot Redis
CHAPTER 14
Spring Boot MongoDB
141 开始使用 MongoDB
142 Maven 依赖
1 ltparentgt2 ltgroupIdgtorgspringframeworkbootltgroupIdgt3 ltartifactIdgtspring-boot-starter-parentltartifactIdgt4 ltversiongt221RELEASEltversiongt5 ltrelativePathgt lt-- lookup parent from repository --gt6 ltparentgt7
8 ltdependencygt9 ltgroupIdgtorgspringframeworkbootltgroupIdgt
10 ltartifactIdgtspring-boot-starter-data-mongodbltartifactIdgt11 ltdependencygt12 ltdependencygt13 ltgroupIdgtorgspringframeworkbootltgroupIdgt14 ltartifactIdgtspring-boot-starter-webltartifactIdgt15 ltdependencygt
85
Spring-Cloud Documentation 发布 10
143 CRUD
1431 Entity
1 package comexamplemongodbentity2
3 import orgspringframeworkdataannotationId4 import orgspringframeworkdatamongodbcoremappingDocument5
6 Document7 public class Customer 8
9 Id10 public String id11
12 public String firstName13 public String lastName14
15 public Customer() 16 17
18 public Customer(String firstName String lastName) 19 thisfirstName = firstName20 thislastName = lastName21 22
23 Override24 public String toString() 25 return Stringformat(Customer[id=s firstName=s lastName=s] id
rarrfirstName lastName)26 27
28
1432 Repository
1 package comexamplemongodbrepository2
3 import javautilList(下页继续)
86 Chapter 14 Spring Boot MongoDB
Spring-Cloud Documentation 发布 10
(续上页)
4
5 import orgspringframeworkdatamongodbrepositoryMongoRepository6 import orgspringframeworkstereotypeRepository7
8 import comexamplemongodbentityCustomer9
10 Repository11 public interface CustomerRepository extends MongoRepositoryltCustomer Stringgt 12
13 public Customer findByFirstName(String firstName)14 public ListltCustomergt findByLastName(String lastName)15
16
1433 Service
1 package comexamplemongodbservice2
3 import javautilList4
5 import orgspringframeworkbeansfactoryannotationAutowired6 import orgspringframeworkstereotypeService7
8 import comexamplemongodbentityCustomer9 import comexamplemongodbrepositoryCustomerRepository
10
11 Service12 public class CustomerService 13
14 Autowired15 private CustomerRepository customerRepository16
17 public ListltCustomergt getCustomers() 18 customerRepositorydeleteAll()19
20 save a couple of customers21 customerRepositorysave(new Customer(Alice Smith))22 customerRepositorysave(new Customer(Bob Smith))23
(下页继续)
143 CRUD 87
Spring-Cloud Documentation 发布 10
(续上页)
24 fetch all customers25 Systemoutprintln(Customers found with findAll())26 Systemoutprintln(-------------------------------)27 ListltCustomergt customers = customerRepositoryfindAll()28 for (Customer customer customers) 29 Systemoutprintln(customer)30 31 Systemoutprintln()32
33 fetch an individual customer34 Systemoutprintln(Customer found with findByFirstName(Alice))35 Systemoutprintln(--------------------------------)36 Systemoutprintln(customerRepositoryfindByFirstName(Alice))37
38 Systemoutprintln(Customers found with findByLastName(Smith))39 Systemoutprintln(--------------------------------)40 for (Customer customer customerRepositoryfindByLastName(Smith)) 41 Systemoutprintln(customer)42 43 return customers44
45 46
47
1434 RestController
1 package comexamplemongodbcontroller2
3 import javautilList4
5 import orgspringframeworkbeansfactoryannotationAutowired6 import orgspringframeworkhttpResponseEntity7 import orgspringframeworkwebbindannotationGetMapping8 import orgspringframeworkwebbindannotationRestController9
10 import comexamplemongodbentityCustomer11 import comexamplemongodbserviceCustomerService12
(下页继续)
88 Chapter 14 Spring Boot MongoDB
Spring-Cloud Documentation 发布 10
(续上页)
13 RestController14 public class CustomerController 15
16 Autowired17 private CustomerService customerService18
19 GetMapping(customer)20 public ResponseEntityltListltCustomergtgt getCustomer(String name) 21 return ResponseEntityok(customerServicegetCustomers())22 23
1435 applicationproperties
springdatamongodbusername=root_appspringdatamongodbpassword=root123springdatamongodbdatabase=mymongospringdatamongodbport=27017springdatamongodbhost=localhost
1436 Mongodb
1 访问httplocalhost8080customer 显示如下
[id5de08e14afacb903cc733ac9firstNameAlicelastNameSmithid5de08e14afacb903cc733acafirstNameBoblastNameSmith]
2 Mongodb 客户端
143 CRUD 89
Spring-Cloud Documentation 发布 10
144 参考
httpsspringioguidesgsaccessing-data-mongodb
90 Chapter 14 Spring Boot MongoDB
91
Spring-Cloud Documentation 发布 10
CHAPTER 15
Spring Boot Auto-Configuration
151 理解 auto-configuration
1511 学习 auto-configuration 如何工作的
152 定制 Spring Boot
1521 利用 Spring Boot properties 进行定制
1522 替换已生成的 Bean
1523 禁用特定的 auto-configuration 类
1524 修改库的依赖
153 基于属性的配置外部化
1531 属性的覆盖(overridden)顺序
1532 重命名 applicationproperties 文件
154 外部配置应用程序属性
1541 使用 EnableConfigurationProperties 注解
155 基于日志记录的调优
1551 输出日志记录
156 使用 YAML 配置文件
1561 YAML 里面的层级属性
1562 单一 YAML 文件中的多个 profiles 属性
157 定制应用程序错误页面
158 小结
92 Chapter 15 Spring Boot Auto-Configuration
CHAPTER 16
Spring Boot Security
161 Spring Boot Security 介绍
httpswwwjavainusecomspringsprboot_sec
1611 启用 Security
1 ltdependencygt2 ltgroupIdgtorgspringframeworkbootltgroupIdgt3 ltartifactIdgtspring-boot-starter-securityltartifactIdgt4 ltdependencygt
16111 覆盖默认用户和密码
By adding some configuration into the applicationproperties file
1 springsecurityusername=user2 springsecurityuserpassword=password
93
Spring-Cloud Documentation 发布 10
1612 禁用 Security
To discard the security auto-configuration and add our own configuration we need to exclude the Secu-rityAutoConfiguration class
This can be done via a simple exclusion
1 SpringBootApplication(exclude = SecurityAutoConfigurationclass )2 public class SpringBootSecurityApplication 3
4 public static void main(String[] args) 5 SpringApplicationrun(SpringBootSecurityApplicationclass args)6 7
Or by adding some configuration into the applicationproperties file
springautoconfigureexclude=orgspringframeworkbootautoconfiguresecurityrarrSecurityAutoConfiguration
在某些特殊情况下此设置还不够
例如如果 classpath中有 Actuator的我们需要继续排除 ManagementWebSecurityAutoConfiguration类
1613 定制 Security
1 Configuration2 EnableWebSecurity3 public class BasicConfiguration extends WebSecurityConfigurerAdapter 4
5 Override6 protected void configure(AuthenticationManagerBuilder auth)7 throws Exception 8 auth9 inMemoryAuthentication()
10 withUser(user)11 password(password)12 roles(USER)13 and()14 withUser(admin)15 password(admin)16 roles(USER ADMIN)
(下页继续)
94 Chapter 16 Spring Boot Security
Spring-Cloud Documentation 发布 10
(续上页)
17 18
19 Override20 protected void configure(HttpSecurity http) throws Exception 21 http22 authorizeRequests()23 anyRequest()24 authenticated()25 and()26 httpBasic()27 28
162 OAuth2 Auto-Configuration
httpswwwjavainusecomspringspring-boot-oauth-introduction
OAuth (Open Authorization) is a simple way to publish and interact with protected data It is an openstandard for token-based authentication and authorization on the Internet It allows an end userrsquos accountinformation to be used by third-party services such as Facebook without exposing the userrsquos password
Spring Boot has a dedicated auto-configuration support for OAuth2 httpsdocsspringiospring-security-oauth2-bootdocscurrentreferencehtmlsingle
Before we get to that letrsquos add the Maven dependency to start setting up our application
1 ltdependencygt2 ltgroupIdgtorgspringframeworksecurityoauthbootltgroupIdgt3 ltartifactIdgtspring-security-oauth2-autoconfigureltartifactIdgt4 ltdependencygt
This dependency includes a set of classes that are capable of triggering the auto-configuration mechanismdefined in OAuth2AutoConfiguration class
163 JWT
httpswwwjavainusecomspringjwt
162 OAuth2 Auto-Configuration 95
Spring-Cloud Documentation 发布 10
1631 JWT
During the first request the client sends a POST request with username and password Upon successfulauthentication the server generates the JWT sends this JWT to the client This JWT can contain a payloadof data On all subsequent requests the client sends this JWT token in the header Using this token theserver authenticates the user So we donrsquot need the client to send the user name and password to the serverduring each request for authentication but only once after which the server issues a JWT to the client AJWT payload can contain things like user ID so that when the client again sends the JWT you can be surethat it is issued by you and you can see to whom it was issued
164 参考
bull httpsgithubibmcomlanzejunfullstacktreemasterspringjwt
bull httpsmediumcomswlhspring-boot-security-jwt-hello-world-example-b479e457664c
bull httpswwwjavainusecomspringjwt
bull httpswwwbaeldungcomjava-config-spring-security
bull httpsdocsspringiospring-securitysitedocscurrentguideshtml5helloworld-boothtml
96 Chapter 16 Spring Boot Security
CHAPTER 17
Spring Boot Actuator
171 Actuator 介绍
在本节中我们将介绍 Spring Boot Actuator我们将首先介绍基础知识然后详细讨论 Spring Boot 1x 和2x 中的可用内容
本质上Actuator为 Spring Boot的应用带来了监控生产应用的功能监视应用程序收集指标了解流量或数据库状态Actuator 的主要好处是我们可以获得生产级工具而不必自己真正实现这些功能Actuator主要用于公开有关正在运行的应用程序的操作信息-运行状况指标信息dump环境等它使用 HTTPendpoints 或 JMX Bean 使我们能够与其交互
一旦 Actuator 的依赖关系位于类路径 classpath 上用户可以立即使用某些 endpoints与大多数 Spring 模块一样我们可以通过多种方式轻松地对其进行配置或扩展
172 启用 Actuator
要在您的应用程序中启用 Spring Boot Actuator您必须在包管理器中添加 Spring Boot Actuator 依赖项通过添加 Starter 依赖项 spring-boot-starter-actuator这是在 Spring 应用程序中启用 actuator 功能的最简单方法
bull Maven 工程中
1 ltdependenciesgt2 ltdependencygt
(下页继续)
97
Spring-Cloud Documentation 发布 10
(续上页)
3 ltgroupIdgtorgspringframeworkbootltgroupIdgt4 ltartifactIdgtspring-boot-starter-actuatorltartifactIdgt5 ltdependencygt6 ltdependenciesgt
bull Gradle 工程中
1 dependencies 2 compile(orgspringframeworkboot spring-boot-starter-actuator)3
173 Spring Boot 1X 中的 Actuator
在 1x 中执行器遵循 RW 模型这意味着我们可以对其进行读取或写入例如我们可以检索指标或应用程序的运行状况另外我们可以优雅地终止我们的应用程序或更改日志记录配置
为了使其工作Actuator 要求 Spring MVC 通过 HTTP 公开其 endpoints不支持其他技术
在 1x 中Actuator 带来了自己的安全模型它利用了 Spring Security 安全架构但是需要与应用程序的其余部分独立配置而且大多数 endpoints 都是 sensitive 状态即私密的这意味着它们不是完全公开的换句话说大多数信息将被省略例如metrics
1731 分析 Actuator 的接口
In 1x Here are some of the most common endpoints Boot provides out of the box
bull health ndash Shows application health information (a simple lsquostatusrsquowhen accessed over an unauthen-ticated connection or full message details when authenticated) itrsquos not sensitive by default
bull info ndash Displays arbitrary application info not sensitive by default
bull metrics ndash Shows lsquometricsrsquoinformation for the current application itrsquos also sensitive by default
bull trace ndash Displays trace information (by default the last few HTTP requests)
我们可以在官方文档中找到现有 endpoints 的完整列表httpsdocsspringiospring-bootdocscurrentreferencehtmlsingleproduction-ready-endpoints
1732 显示配置细节
httplocalhost8080health
98 Chapter 17 Spring Boot Actuator
Spring-Cloud Documentation 发布 10
1733 利用接口显示指标
1 endpointsmetricssensitive=false2 endpointsmetricsenabled=true
httplocalhost8080metrics
1734 显示应用程序信息
1 infoappname=Spring Sample Application2 infoappdescription=This is my first spring boot application3 infoappversion=100
1735 关闭应用程序
1736 自定义 Actuator
1 package comdoceditfsd2
3 import orgspringframeworkbootactuatehealthHealth4 import orgspringframeworkbootactuatehealthHealthIndicator5 import orgspringframeworkstereotypeComponent6
7 Component8 public class HealthCheck implements HealthIndicator 9
10 Override11 public Health health() 12 int errorCode = check() perform some specific health check13 if (errorCode = 0) 14 return Healthdown()withDetail(Error Code errorCode)build()15 16 return Healthup()build()17 18
19 public int check() 20 Our logic to check health21 Systemoutprintln(Our logic to check health)22 return 0
(下页继续)
173 Spring Boot 1X 中的 Actuator 99
Spring-Cloud Documentation 发布 10
(续上页)
23 24
17361 启用或禁用某个 Actuator 接口
endpointsbeansenabled=true
17362 更改接口 ID
endpointsbeansid=springbeans
17363 更改 Actuator 接口的灵敏度
endpointsbeanssensitive=false
17364 编写自定义健康指标
1 启用 metrics
1 endpointsmetricssensitive=false2 endpointsmetricsenabled=true
2 编写 CounterService
1 package comdoceditfsd2
3 import orgspringframeworkbeansfactoryannotationAutowired4 import orgspringframeworkbootactuatehealthHealth5 import orgspringframeworkbootactuatehealthHealthIndicator6 import orgspringframeworkbootactuatemetricsCounterService7 import orgspringframeworkstereotypeComponent8
9 Component10 public class HealthCheck implements HealthIndicator 11
12 Autowired13 private CounterService counterService14
15 Override16 public Health health()
(下页继续)
100 Chapter 17 Spring Boot Actuator
Spring-Cloud Documentation 发布 10
(续上页)
17 int errorCode = check() perform some specific health check18 if (errorCode = 0) 19 return Healthdown()withDetail(Error Code errorCode)build()20 21 return Healthup()build()22 23
24 public int check() 25 Our logic to check health26 Systemoutprintln(Our logic to check health)27 counterServiceincrement(counterloginsuccess) test gather
rarrcustom metrics28 counterServiceincrement(counterloginfailure) test gather
rarrcustom metrics29 return 030 31
3 访问 httplocalhost8080health 目的是触发 counterServiceincrement 方法
4 接着访问 httplocalhost8080metrics 显示下面的指标信息
counterloginfailure1counterloginsuccess1counterstatus200health1
1737 创建一个自定义 Endpoint
1 创建 CustomEndpoint
1 Component2 public class CustomEndpoint implements EndpointltListltStringgtgt 3
4 Override5 public String getId() 6 return customEndpoint7 8
9 Override10 public boolean isEnabled() 11 return true12
(下页继续)
173 Spring Boot 1X 中的 Actuator 101
Spring-Cloud Documentation 发布 10
(续上页)
13
14 Override15 public boolean isSensitive() 16 return true17 18
19 Override20 public ListltStringgt invoke() 21 Custom logic to build the output22 ListltStringgt messages = new ArrayListltStringgt()23 messagesadd(This is message 1)24 messagesadd(This is message 2)25 return messages26 27
2 接着访问 httplocalhost8080customEndpoint或者用 CURL 检查
curl -H Content-Typeapplicationjson httplocalhost8080customEndpoint
1738 对 Actuator 接口进行安全控制
在 1x 中Actuator 基于 Spring Security 配置其自己的安全模型但与应用程序的其余部分无关默认情况下除 info 外的所有内置 Endpoint 都是私密的如果应用程序使用的是 Spring Security我们可以通过在 applicationproperties 文件中定义默认的安全属性(用户名密码和角色)来保护这些 endpoints
securityusername=adminsecurityuserpassword=secretmanagementsecurityrole=SUPERUSER
添加 security 依赖
1 ltdependencygt2 ltgroupIdgtorgspringframeworkbootltgroupIdgt3 ltartifactIdgtspring-boot-starter-securityltartifactIdgt4 ltdependencygt
102 Chapter 17 Spring Boot Actuator
Spring-Cloud Documentation 发布 10
1739 Further Customization
为了安全起见我们可能选择通过非标准端口公开 Actuator endpoints可以使用 managementport 属性进行配置
1 port used to expose actuator2 managementport=80813
4 CIDR allowed to hit actuator5 managementaddress=1270016
7 Whether security should be enabled or disabled altogether8 managementsecurityenabled=false
174 Spring Boot 2X 中的 Actuator
在 2x 中默认情况下现在所有 Actuator endpoints 都放在 actuator 路径下且只有两个默认是公开的health 和 info其他的默认是私密的
我们使用新的属性 managementendpointswebbase-path 来调整默认的 actuator 路径
1741 分析 Actuator 的接口
bull auditevents ndash lists security audit-related events such as user loginlogout Also we can filter byprincipal or type among others fields
bull beans ndash returns all available beans in our BeanFactory Unlike auditevents it doesnrsquot supportfiltering
bull conditions ndash formerly known as autoconfig builds a report of conditions around auto-configuration
bull configprops ndash allows us to fetch all ConfigurationProperties beans
bull env ndash returns the current environment properties Additionally we can retrieve single properties
bull flyway ndash provides details about our Flyway database migrations
bull health ndash summarises the health status of our application
bull heapdump ndash builds and returns a heap dump from the JVM used by our application
bull info ndash returns general information It might be custom data build information or details about thelatest commit
bull liquibase ndash behaves like flyway but for Liquibase
bull logfile ndash returns ordinary application logs
174 Spring Boot 2X 中的 Actuator 103
Spring-Cloud Documentation 发布 10
bull loggers ndash enables us to query and modify the logging level of our application
bull metrics ndash details metrics of our application This might include generic metrics as well as custom ones
bull prometheus ndash returns metrics like the previous one but formatted to work with a Prometheus server
bull scheduledtasks ndash provides details about every scheduled task within our application
bull sessions ndash lists HTTP sessions given we are using Spring Session
bull shutdown ndash performs a graceful shutdown of the application
bull threaddump ndash dumps the thread information of the underlying JVM
在 Spring Boot 20 中内部 metrics 已被 Micrometer 支持所取代因此如果我们的应用程序使用的是GaugeService 或 CounterService则它们将不再可用
17411 启用或禁用某个 Endpoint
如果要启用所有这些功能可以设置
managementendpointswebexposureinclude=
要显式启用特定 endpoint(例如 shutdown)我们使用
managementendpointshutdownenabled=true
或者我们可以列出应启用的具体 endpoints
managementendpointswebexposureinclude=beansmetrics
要公开排除一个(例如 loggers)以外的所有启用的 endpoints我们使用
managementendpointswebexposureinclude=managementendpointswebexposureexclude=loggers
1742 创建一个自定义 endpoint
1 package comdoceditfsd2
3 import orgspringframeworkbootactuateendpointannotationEndpoint4 import orgspringframeworkbootactuateendpointannotationReadOperation5 import orgspringframeworkstereotypeComponent6
7 Endpoint(id=mypoint)(下页继续)
104 Chapter 17 Spring Boot Actuator
Spring-Cloud Documentation 发布 10
(续上页)
8 Component9 public class MyPointEndPoint
10 ReadOperation11 public String mypoint()12 return Hello 13 14
我们可以使用以下声明定义操作
bull ReadOperation ndash 对应 HTTP GET
bull WriteOperation ndash 对应 HTTP POST
bull DeleteOperation ndash 对应 HTTP DELETE
1743 显示 git 详细信息
1 添加 git plugin
1 ltplugingt2 ltgroupIdgtplproject13mavenltgroupIdgt3 ltartifactIdgtgit-commit-id-pluginltartifactIdgt4 ltconfigurationgt5 ltdotGitDirectorygt$projectbasedirgitltdotGitDirectorygt6 ltconfigurationgt7 ltplugingt
2 执行 mvn clean package 命令后将会生成文件targetclassesgitproperties
macbook-profsd2x murphy$ cat targetclassesgitpropertiesGenerated by Git-Commit-Id-PluginFri Oct 11 151712 CST 2019gitbranch=mastergitbuildhost=macbook-procnibmcomgitbuildtime=2019-10-11T151712+0800gitbuilduseremail=lanzejuncnibmcomgitbuildusername=lanzejungitbuildversion=001-SNAPSHOTgitclosesttagcommitcount=gitclosesttagname=gitcommitid=60201666e9ec6088da5072c1b19c27f686cc9a2c
(下页继续)
174 Spring Boot 2X 中的 Actuator 105
Spring-Cloud Documentation 发布 10
(续上页)
gitcommitidabbrev=6020166gitcommitiddescribe=6020166-dirtygitcommitiddescribe-short=6020166-dirtygitcommitmessagefull=updategitcommitmessageshort=updategitcommittime=2019-10-09T170228+0800gitcommituseremail=lanzejuncnibmcomgitcommitusername=lanzejungitdirty=truegitremoteoriginurl=gitgithubibmcomlanzejunfullstackgitgittags=gittotalcommitcount=70
3 查看 infohttplocalhost8080actuatorinfo默认情况下显示的节点信息仅有 3 个
17431 指定 git 地址
1 ltconfigurationgt2 ltdotGitDirectorygt$projectbasedirgitltdotGitDirectorygt3 ltconfigurationgt
其中 $projectbasedir 指的是当前项目的根目录
17432 显示全部信息
在 applicationproperties 文件中添加
managementinfogitmode=full
17433 关闭 gitproperties 文件的创建
在 configuration 中添加
ltgenerateGitPropertiesFilegtfalseltgenerateGitPropertiesFilegt
17434 Verbosity
显示细粒度的日志信息在 configuration 中添加
106 Chapter 17 Spring Boot Actuator
Spring-Cloud Documentation 发布 10
ltverbosegttrueltverbosegt
17435 过滤敏感信息
在 configuration 中添加
1 ltexcludePropertiesgt2 ltexcludePropertygtgituserltexcludePropertygt3 ltexcludePropertiesgt
1744 对 Actuator 接口进行安全控制
Actuator 与常规 Spring Security 规则共享安全配置因此要调整 Actuator 安全性规则我们可以为路径添加一个例外如actuator
添加 security 依赖
1 ltdependencygt2 ltgroupIdgtorgspringframeworkbootltgroupIdgt3 ltartifactIdgtspring-boot-starter-securityltartifactIdgt4 ltdependencygt
1 Bean2 public SecurityWebFilterChain securityWebFilterChain(3 ServerHttpSecurity http) 4 return httpauthorizeExchange()5 pathMatchers(actuator)permitAll()6 anyExchange()authenticated()7 and()build()8
175 spring-boot-admin
httpswwwbaeldungcomspring-boot-admin
176 参考
bull httpsdocsspringiospring-bootdocs220BUILD-SNAPSHOTreferencehtmlproduction-ready-featureshtmlproduction-ready-endpoints
175 spring-boot-admin 107
Spring-Cloud Documentation 发布 10
bull httpsdocsspringiospring-bootdocs20xactuator-apihtml
bull httpswwwbaeldungcomspring-boot-security-autoconfiguration
177 小结
108 Chapter 17 Spring Boot Actuator
CHAPTER 18
Spring Boot RESTful
181 基于 Spring Boot 的微服务
1811 bootstrapyml 和 applicationyml 简介
1812 简单的微服务示例
182 Spring Data 简介
1821 Apache Ignite 存储库
1822 Spring Data MongoDB
1823 Spring Data JPA
183 小结
109
Spring-Cloud Documentation 发布 10
110 Chapter 18 Spring Boot RESTful
CHAPTER 19
Springfox-Swagger2
191 Maven Dependency
1 ltdependencygt2 ltgroupIdgtiospringfoxltgroupIdgt3 ltartifactIdgtspringfox-swagger2ltartifactIdgt4 ltversiongt292ltversiongt5 ltdependencygt6 ltdependencygt7 ltgroupIdgtiospringfoxltgroupIdgt8 ltartifactIdgtspringfox-swagger-uiltartifactIdgt9 ltversiongt292ltversiongt
10 ltdependencygt
192 Configuration
1 Configuration2 EnableSwagger23 public class SwaggerConfig 4 Bean5 public Docket api()
(下页继续)
111
Spring-Cloud Documentation 发布 10
(续上页)
6 return new Docket(DocumentationTypeSWAGGER_2)7 select()8 apis(RequestHandlerSelectorsany())9 paths(PathSelectorsany())
10 build()11 12
193 Verification
bull httplocalhost8080swagger-uihtml
bull httplocalhost8080v2api-docs
194 参考
httpswwwbaeldungcomswagger-2-documentation-for-spring-rest-api
112 Chapter 19 Springfox-Swagger2
CHAPTER 20
Spring Cloud
201 原生云应用程序架构
问题集httpswwwjavainusecomspringspring-cloud-interview-questions
2011 微服务架构
2012 微服务的优点
2013 微服务面临的挑战
202 简介
Spring Cloud 是一系列框架的有序集合它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发如服务发现注册配置中心消息总线负载均衡断路器数据监控等都可以用 Spring Boot的开发风格做到一键启动和部署Spring 并没有重复制造轮子它只是将目前各家公司开发的比较成熟经得起实际考验的服务框架组合起来通过 Spring Boot 风格进行再封装屏蔽掉了复杂的配置和实现原理最终给开发者留出了一套简单易懂易部署和易维护的分布式系统开发工具包
113
Spring-Cloud Documentation 发布 10
2021 云和微服务程序的构造块
2022 Spring Cloud 应用
203 配置 Spring Cloud 应用程序
Spring Cloud 是一个总括项目由原则上具有不同发布节奏的独立项目组成为了管理项目组合将发布BOM(物料清单)并带有对单个项目的精选依赖关系集(请参见下文)发行列车使用名称而不是版本以避免与子项目混淆名称是按字母顺序排列的(因此您可以按时间顺序对其进行排序)带有伦敦地铁站的名称(ldquoAngelrdquo是第一个发行版ldquoBrixtonrdquo是第二个发行版)当各个项目的点发布积累到一定数量时或者其中一个关键错误需要所有人使用时发布培训将推出名称以ldquoSRXrdquo结尾的ldquo服务版本rdquo其中ldquoXrdquo是数字
表 1 Spring Cloud RELEASE 版本
RELEASE 名称 对应 Spring Boot 的版本Hoxton 22xGreenwich 21xFinchley 20xEdgware 15xDalston 15x
比如(注意高亮行)
1 ltxml version=10 encoding=UTF-8gt2 ltproject xmlns=httpmavenapacheorgPOM4003 xmlnsxsi=httpwwww3org2001XMLSchema-instance4 xsischemaLocation=httpmavenapacheorgPOM400 httpsmavenapacheorgxsd
rarrmaven-400xsdgt5 ltmodelVersiongt400ltmodelVersiongt6 ltparentgt7 ltgroupIdgtorgspringframeworkbootltgroupIdgt8 ltartifactIdgtspring-boot-starter-parentltartifactIdgt9 ltversiongt219RELEASEltversiongt
10 ltrelativePath gt lt-- lookup parent from repository --gt11 ltparentgt12 ltgroupIdgtcomdoceditltgroupIdgt13 ltartifactIdgtspring-cloud-config-serverltartifactIdgt14 ltversiongt001-SNAPSHOTltversiongt15 ltnamegtspring-cloud-config-serverltnamegt16 ltdescriptiongtDemo project for Spring Bootltdescriptimiddotongt
(下页继续)
114 Chapter 20 Spring Cloud
Spring-Cloud Documentation 发布 10
(续上页)
17
18 ltpropertiesgt19 ltjavaversiongt18ltjavaversiongt20 ltmaven-jar-pluginversiongt311ltmaven-jar-pluginversiongt21 ltspring-cloudversiongtGreenwichRELEASEltspring-cloudversiongt22 ltpropertiesgt23
24 ltdependenciesgt25 ltdependencygt26 ltgroupIdgtorgspringframeworkbootltgroupIdgt27 ltartifactIdgtspring-boot-starterltartifactIdgt28 ltdependencygt29
30 ltdependencygt31 ltgroupIdgtorgspringframeworkcloudltgroupIdgt32 ltartifactIdgtspring-cloud-config-serverltartifactIdgt33 ltdependencygt34
35 ltdependencygt36 ltgroupIdgtorgspringframeworkbootltgroupIdgt37 ltartifactIdgtspring-boot-starter-testltartifactIdgt38 ltscopegttestltscopegt39 ltdependencygt40 ltdependenciesgt41
42 ltdependencyManagementgt43 ltdependenciesgt44 ltdependencygt45 ltgroupIdgtorgspringframeworkcloudltgroupIdgt46 ltartifactIdgtspring-cloud-dependenciesltartifactIdgt47 ltversiongt$spring-cloudversionltversiongt48 lttypegtpomlttypegt49 ltscopegtimportltscopegt50 ltdependencygt51 ltdependenciesgt52 ltdependencyManagementgt53
54 ltbuildgt55 ltpluginsgt56 ltplugingt
(下页继续)
203 配置 Spring Cloud 应用程序 115
Spring-Cloud Documentation 发布 10
(续上页)
57 ltgroupIdgtorgspringframeworkbootltgroupIdgt58 ltartifactIdgtspring-boot-maven-pluginltartifactIdgt59 ltplugingt60 ltpluginsgt61 ltbuildgt62
63 ltprojectgt
204 小结
116 Chapter 20 Spring Cloud
CHAPTER 21
Spring Cloud Config
211 介绍
Spring Cloud Config 是 Spring Cloud 团队创建的一个全新项目用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持它分为服务端和客户端两部分其中服务端也称为分布式配置中心它是一个独立的微服务应用用来连接配置仓库并为客户端提供获取配置信息加密解密信息等访问接口而客户端则是微服务架构中的各个微服务应用或基础设施它们通过指定的配置中心管理应用资源与业务相关的配置内容并在启动的时候从配置中心获取和加载配置信息
212 配置 Server
Spring Cloud Config 服务端对应的组件是spring-cloud-config-server
2121 搭建项目
1 添加 spring-cloud-config-server 依赖
1 ltdependencygt2 ltgroupIdgtorgspringframeworkbootltgroupIdgt3 ltartifactIdgtspring-boot-starter-webltartifactIdgt4 ltdependencygt5
(下页继续)
117
Spring-Cloud Documentation 发布 10
(续上页)
6 ltdependencygt7 ltgroupIdgtorgspringframeworkcloudltgroupIdgt8 ltartifactIdgtspring-cloud-config-serverltartifactIdgt9 ltdependencygt
2 编辑文件 applicationproperties
1 serverport=88882 springapplicationname=cloud-config3 springcloudconfigservergituri=file$userhomeapp-config-repo
注意属性 springapplicationname的值 cloud-config对应 uri中的 path属性 springapplicationname的值同时对应 uri 属性路径中的文件名这里表示在目录 $userhomeapp-config-repo 下有文件cloud-config-properties
2122 创建 Git 存储库
服务器存储后端的默认实现使用 git我们需要创建 Git 存储库作为配置存储
$ cd $HOME$ mkdir app-config-repo$ cd app-config-repo$ git init $ echo userrole=Dev gt cloud-config-developmentproperties$ echo userrole=Admin gt cloud-config-productionproperties$ git add $ git commit -m Initial application properties
2123 检验内容
1 打开浏览器访问地址httplocalhost8888cloud-configdevelopment
2 切换地址httplocalhost8888cloud-configproduction
213 配置 Client
Spring Cloud Config 客户端对应的组件是spring-cloud-starter-client
118 Chapter 21 Spring Cloud Config
Spring-Cloud Documentation 发布 10
2131 搭建项目
1 添加 spring-cloud-starter-client 依赖
1 ltdependencygt2 ltgroupIdgtorgspringframeworkbootltgroupIdgt3 ltartifactIdgtspring-boot-starter-webltartifactIdgt4 ltdependencygt5
6 ltdependencygt7 ltgroupIdgtorgspringframeworkcloudltgroupIdgt8 ltartifactIdgtspring-cloud-starter-clientltartifactIdgt9 ltdependencygt
2 编辑文件 applicationproperties
1 springapplicationname=cloud-client2 springprofilesactive=development3 springcloudconfiguri=httplocalhost8888
bull 属性 springapplicationname 的值同时对应 uri 属性路径中的文件名这里表示在目录$userhomeapp-config-repo 下有文件 cloud-client-properties
3 创建客户端 Controller
1 package comdoceditspringcloudconfigserver2
3 import orgspringframeworkbeansfactoryannotationValue4 import orgspringframeworkwebbindannotationGetMapping5 import orgspringframeworkwebbindannotationPathVariable6 import orgspringframeworkwebbindannotationRestController7
8 RestController9 public class ConfigClientController
10
11 Value($userrole)12 private String role13
14 GetMapping(profilename)15 public String getActiveProfile(PathVariable String name) 16 return Hello + name + active profile name is + role17 18
(下页继续)
213 配置 Client 119
Spring-Cloud Documentation 发布 10
(续上页)
19
2132 创建客户端属性文件
这里需要创建 cloud-client-properties 文件
$ cd $HOME$ cd app-config-repo$ echo userrole=abc123 gt cloud-clientproperties$ git add $ git commit -m add application properties
2133 检验内容
1 打开浏览器访问地址httplocalhost8080profilemurphy页面将显示
Hello murphy active profile name is abc123
120 Chapter 21 Spring Cloud Config
CHAPTER 22
Spring Cloud Netflix
Spring Cloud Netflix 是对 Netflix 开发的一套分布式服务框架的封装包括服务的发现和注册负载均衡断路器REST 客户端请求路由等它是 Spring Cloud 的一部分
221 Netflix
Netflix OSS是一组开源的框架和组件库是 Netflix公司开发出来解决分布式系统的一些有趣的可扩展类库Spring Cloud把他们都放到 Spring Cloud Netflix下这是一个框架集合它包括 EurekaRibbonHystrixZuulGateway 等
Eureka 服务中心这可以说是微服务架构的核心功能了微服务部署之后一定要有服务注册和发现的能力Eureka 就是担任这个角色的
Ribbon 提供客户端负责均衡功能例如一个服务提供者部署了 3 个实例那么使用 Ribbon 可以指定负载均衡算法请求其中一个实例Ribbon 如果配合 Eureka 使用起来非常简单
Hystrix 熔断器假设有 3 个服务提供实例其中有一个实例由于某种原因挂掉了那么当再有请求进来的时候如果还是向这个实例上发请求那将会导致请求积压阻塞这个时候熔断器就要发挥它的作用将这个有问题的实例下线这样一来再有新的请求进来就不会再发到这个有问题的实例上了
Zuul 服务网关主要实现了路由转发和过滤器功能对于处理一些数据聚合鉴权监控统计类的功能非常好用
Gateway 也是服务网关可以认为它是 Zuul 的下一代无论从易用性和性能方便都有所提高如果你的系统中还没有使用 Zuul 并且准备上网关可以直接选择 Gateway
121
Spring-Cloud Documentation 发布 10
222 小结
122 Chapter 22 Spring Cloud Netflix
CHAPTER 23
Spring Cloud Eureka
本节将通过 Spring Cloud Netflix Eureka 介绍客户端服务发现和负载平衡
231 服务发现
在典型的微服务体系结构中我们有许多单独部署的小型应用程序它们经常需要彼此通信具体地说当我们说客户服务时我们指的是需要对其他终端服务进行 REST 调用的服务
这种体系结构中的问题是客户端服务如何找到其所有最终服务我们可以在某些属性文件中对主机名端口进行硬编码但这在云环境中并不总是可行可能有任意数量的微服务并且当数量不确定且它们的位置可能发生变化时进行硬编码很费时间和资源
因此微服务中引入了服务发现组件也就是注册中心一般使用 Eureka也有其他的组件Consulzookeeper等实际使用中将微服务都注册到注册中心注册中已经包含了微服务的 ip 等信息这样微服务之间互相调用时就可以现在注册中心获取对应微服务的 ip 信息这样就不用自己维护很多的配置文件了
232 Eureka
Eureka 是 Netflix 开源的服务发现组件本身是一个基于 REST 的服务包含 Server 和 Client 两部分Spring Cloud 将它集成在子项目 Spring Cloud Netflix 中在微服务系统中我们需要单独创建一个 EurekaServer 作为注册中心其他的微服务就相当于客户端注册到我们的注册中心中
123
Spring-Cloud Documentation 发布 10
2321 Eureka Server
实施 Eureka Server 进行服务注册非常简单
1 将 spring-cloud-starter-netflix-eureka-server 添加到依赖项
2 通过使用 EnableEurekaServer 注解在 SpringBootApplication 中启用 Eureka 服务器
3 配置一些属性
下面我们将逐步进行
1 添加依赖项
1 ltdependencygt2 ltgroupIdgtorgspringframeworkbootltgroupIdgt3 ltartifactIdgtspring-boot-starter-webltartifactIdgt4 ltdependencygt5
6 ltdependencygt7 ltgroupIdgtorgspringframeworkcloudltgroupIdgt8 ltartifactIdgtspring-cloud-starter-netflix-eureka-serverltartifactIdgt9 ltdependencygt
2 添加 EnableEurekaServer 注解
1 package comdoceditspringcloudconfigserver2
3 import orgspringframeworkbootSpringApplication4 import orgspringframeworkbootautoconfigureSpringBootApplication5 import orgspringframeworkcloudnetflixeurekaserverEnableEurekaServer6
7 SpringBootApplication8 EnableEurekaServer9 public class SpringCloudEurekaServerApplication
10
11 public static void main(String[] args) 12 SpringApplicationrun(SpringCloudEurekaServerApplicationclass args)13 14
15
3 配置属性
124 Chapter 23 Spring Cloud Eureka
Spring-Cloud Documentation 发布 10
1 serverport=87612 eurekaclientregisterWithEureka=false3 eurekaclientfetchRegistry=false4
5 eurekainstancehostname=localhost6 eurekaclientserviceUrldefaultZone=http$eurekainstancehostname$serverport
rarreureka
在这里我们正在配置一个应用程序端口Eureka服务器的默认端口是 8761我们告诉内置的 Eureka Client不要注册ldquo自己rdquo因为我们的应用程序仅充当服务器httplocalhost8761eureka是默认的 url因此defaultZone 处的配置可以省略
4 检查结果打开浏览器访问地址httplocalhost8761 查看 Eureka 仪表板稍后我们将在其中检查注册的实例
目前我们可以看到基本指标例如状态和健康指标
232 Eureka 125
Spring-Cloud Documentation 发布 10
2322 Eureka Client
为了使 Eureka Client 能够被发现我们必须在类路径 classpath 中包含一些 Spring Discovery Client(例如spring-cloud-starter-netflix-eureka-client)然后我们需要使用 EnableDiscoveryClient或 EnableEureka-Client 标签注意如果我们的类路径 classpath 具有 spring-cloud-starter-netflix-eureka-client 依赖项则EnableDiscoveryClient 或 EnableEurekaClient 是可选的
注解 EnableDiscoveryClient 或 EnableEurekaClient 告诉 Spring Boot 明确使用 Spring Netflix Eureka进行服务发现
1 首先我们将添加依赖项
1 ltdependencygt2 ltgroupIdgtorgspringframeworkcloudltgroupIdgt3 ltartifactIdgtspring-cloud-starter-netflix-eureka-clientltartifactIdgt4 ltdependencygt
2 创建 RestController
1 package comexampletrainingeurekaclientcontroller2
3 import orgspringframeworkbeansfactoryannotationValue4 import orgspringframeworkwebbindannotationGetMapping5 import orgspringframeworkwebbindannotationRestController6
7 RestController8 public class GreetingController 9
10 Value($springapplicationname)11 private String appName12
13 GetMapping(hello)14 public String hello() 15 return Stringformat(Hello from s appName)16 17
3 添加 EnableDiscoveryClient
1 package comexampletrainingeurekaclient2
3 import orgspringframeworkbootSpringApplication4 import orgspringframeworkbootautoconfigureSpringBootApplication
(下页继续)
126 Chapter 23 Spring Cloud Eureka
Spring-Cloud Documentation 发布 10
(续上页)
5 import orgspringframeworkcloudnetflixeurekaEnableEurekaClient6
7 SpringBootApplication8 EnableEurekaClient9 public class TrainingEurekaClientApplication
10
11 public static void main(String[] args) 12 SpringApplicationrun(TrainingEurekaClientApplicationclass args)13 14
15
4 添加 applicationproperties
1 springapplicationname=spring-cloud-eureka-client2 serverport=03 eurekaclientserviceUrldefaultZone=$EUREKA_URIhttplocalhost8761eureka4 eurekainstancepreferIpAddress=true5
6 infoappname=$springapplicationname
bull serverport=0 表示选择一个随机端口因为稍后我们将使用其名称访问此服务
bull eurekainstancepreferIpAddress=true 表示使用 IP 进行注册
bull infoappname 表示返回 healthcheck(ldquoactuatorinfordquo)的内容
注解 $EUREKA_URIhttplocalhost8761eureka这个变量的意思是当存在环境变量 EU-REKA_URI时使用 EUREKA_URI的值如果没有的话默认使用 httplocalhost8761eureka eg inproduction environment
现在我们将运行客户端并将浏览器再次指向 httplocalhost8761以在 Eureka 仪表板上查看其注册状态通过使用仪表板我们可以进行进一步的配置例如为了管理目的将注册客户端的主页与仪表板链接但是配置选项不在本文讨论范围之内
5 打开浏览器访问地址httplocalhost8761 查看 Eureka 仪表板我们将在其中看到已经注册的实例
232 Eureka 127
Spring-Cloud Documentation 发布 10
6 点击仪表盘上面的 Instances currently registered with Eureka 区域中的 link
7 将 url 的后缀改为hello将会看到下面的信息显示
128 Chapter 23 Spring Cloud Eureka
Spring-Cloud Documentation 发布 10
233 发现 REST 服务
各个客户端可能需要相互访问首先需要彼此知道对方存在即发现 REST 服务这里介绍 2 种实现方式
2331 EurekaClient
1 Clone上面的ldquospring-cloud-eureka-clientrdquo项目其中ldquospringapplicationnamerdquo更换为ldquospring-cloud-eureka-eurekaClientrdquo
2 在 GreetingController 中新增一个方法具体代码如下
1 package comexampletrainingeurekaclientcontroller2
3 import orgspringframeworkbeansfactoryannotationAutowired4 import orgspringframeworkbeansfactoryannotationValue5 import orgspringframeworkcontextannotationLazy6 import orgspringframeworkwebbindannotationGetMapping7 import orgspringframeworkwebbindannotationRestController8
9 import comnetflixappinfoInstanceInfo10 import comnetflixdiscoveryEurekaClient11 import comnetflixdiscoverysharedApplication12
13 RestController14 public class GreetingController 15
16 Autowired17 Lazy18 private EurekaClient eurekaClient19
20 Value($springapplicationname)21 private String appName22
23 GetMapping(greeting)24 public String greeting() 25 Application application = eurekaClientgetApplication(spring-cloud-eureka-client
rarr)26 InstanceInfo instanceInfo = applicationgetInstances()get(0)27 String hostname = instanceInfogetHostName()28 int port = instanceInfogetPort()29 return Stringformat(Hello from s s s applicationgetName()
rarrhostname port) (下页继续)
233 发现 REST 服务 129
Spring-Cloud Documentation 发布 10
(续上页)
30 31
32 GetMapping(hello)33 public String hello() 34 return Stringformat(Hello from s eurekaClientgetApplication(appName)
rarrgetName())35 36
bull 代码中注入了 EurekaClient 实体类我们需要延迟加载 EurekaClient因此这里使用 Lazy 注解
bull 通过 EurekaClient 实例我们可以接收一个以 service-name 命名的服务信息作为 Application 对象根据此对象获取该服务的所有实例的列表选择一个合适的实例然后使用此实例获取主机名和端口这样我们可以对任何 http 客户端发出标准请求
3 启动应用后仪表板上将会新增一个实例
6 点击仪表盘上面的 Instances currently registered with Eureka 区域中的 link
7 将 url 的后缀改为greeting将会看到下面的信息显示
130 Chapter 23 Spring Cloud Eureka
Spring-Cloud Documentation 发布 10
2332 DiscoveryClient
1 Clone上面的ldquospring-cloud-eureka-clientrdquo项目其中ldquospringapplicationnamerdquo更换为ldquospring-cloud-eureka-discoveryClientrdquo
2 在 GreetingController 中新增一个方法具体代码如下
1 package comexampletrainingeurekaclientcontroller2
3 import javautilList4 import javautilOptional5
6 import orgspringframeworkbeansfactoryannotationAutowired7 import orgspringframeworkbeansfactoryannotationValue8 import orgspringframeworkcloudclientServiceInstance9 import orgspringframeworkcloudclientdiscoveryDiscoveryClient
10 import orgspringframeworkcontextannotationLazy11 import orgspringframeworkwebbindannotationGetMapping12 import orgspringframeworkwebbindannotationPathVariable13 import orgspringframeworkwebbindannotationRestController14
15 RestController16 public class GreetingController 17
18 Autowired19 Lazy20 private DiscoveryClient discoveryClient21
22 Value($springapplicationname)23 private String appName24
25 GetMapping( get-instances get-instancesapplicationName )26 public ListltServiceInstancegt serviceInstancesByApplicationName(PathVariable Optional
rarrltStringgt applicationName) 27 String newName = appName28 if (applicationNameisPresent()) 29 newName = applicationNameget()30 31
32 return thisdiscoveryClientgetInstances(newName)33 34
233 发现 REST 服务 131
Spring-Cloud Documentation 发布 10
bull 代码中注入了 DiscoveryClient 实体类我们需要延迟加载 DiscoveryClient因此这里使用 Lazy 注解
bull 通过 DiscoveryClient实例我们可以接收一个以 service-name命名的服务信息返回该服务的所有实例的列表选择一个合适的实例然后使用此实例获取主机名和端口这样我们可以对任何 http 客户端发出标准请求
3 启动应用后仪表板上将会新增一个实例
6 点击仪表盘上面的 Instances currently registered with Eureka 区域中的 link
7 将 url 的后缀改为get-instances将会看到下面的信息显示
1 2 host 91121362143 port 565654 metadata 5 instanceId 9112136214spring-cloud-eureka-discoveryClient06 serviceId SPRING-CLOUD-EUREKA-DISCOVERYCLIENT7 secure false8 uri http911213621456565
(下页继续)
132 Chapter 23 Spring Cloud Eureka
Spring-Cloud Documentation 发布 10
(续上页)
9 instanceInfo 10 instanceId 9112136214spring-cloud-eureka-discoveryClient011 app SPRING-CLOUD-EUREKA-DISCOVERYCLIENT12 appGroupName null13 ipAddr 911213621414 sid na15 homePageUrl http91121362145656516 statusPageUrl http911213621456565actuatorinfo17 healthCheckUrl http911213621456565actuatorhealth18 secureHealthCheckUrl null19 vipAddress spring-cloud-eureka-discoveryClient20 secureVipAddress spring-cloud-eureka-discoveryClient21 countryId 122 dataCenterInfo 23 class comnetflixappinfoInstanceInfo$DefaultDataCenterInfo24 name MyOwn25 26 hostName 911213621427 status UP28 overriddenStatus UNKNOWN29 leaseInfo 30 renewalIntervalInSecs 3031 durationInSecs 9032 registrationTimestamp 157311321378733 lastRenewalTimestamp 157311321378734 evictionTimestamp 035 serviceUpTimestamp 157311267899536 37 isCoordinatingDiscoveryServer false38 metadata 39 lastUpdatedTimestamp 157311321378740 lastDirtyTimestamp 157311321322541 actionType ADDED42 asgName null43 44 scheme null45
233 发现 REST 服务 133
Spring-Cloud Documentation 发布 10
234 使用 REST 服务
RestTemplate
httpswwwbaeldungcomrest-template
235 负载平衡
1 我们以工程ldquospring-cloud-eureka-discoveryClientrdquo为例换个不同的端口再部署一个仪表板显示如下
2 点击仪表盘上面的 Instances currently registered with Eureka 区域中的 link然后将 url 的后缀改为get-instances将会看到下面的信息显示
134 Chapter 23 Spring Cloud Eureka
Spring-Cloud Documentation 发布 10
上图显示了 2 个实例信息
下面示例演示 LoadBalanced 注解它提供负载均衡功能
1 package comexampletrainingeurekaclientcontroller2
3 import orgspringframeworkbeansfactoryannotationAutowired4 import orgspringframeworkbeansfactoryannotationValue5 import orgspringframeworkcloudclientloadbalancerLoadBalanced6 import orgspringframeworkcontextannotationBean7 import orgspringframeworkcontextannotationLazy8 import orgspringframeworkwebbindannotationGetMapping9 import orgspringframeworkwebbindannotationRestController
10 import orgspringframeworkwebclientRestTemplate11
12 import comnetflixdiscoveryEurekaClient13
14 RestController15 public class GreetingController 16
17 Autowired18 Lazy
(下页继续)
235 负载平衡 135
Spring-Cloud Documentation 发布 10
(续上页)
19 private EurekaClient eurekaClient20
21 Value($springapplicationname)22 private String appName23
24 LoadBalanced25 Bean26 RestTemplate restTemplate() 27 return new RestTemplate()28 29
30 Autowired31 RestTemplate restTemplate32
33 GetMapping(greeting)34 public String greeting() 35 String greeting = thisrestTemplategetForObject(httpspring-cloud-eureka-
rarrclientgreeting Stringclass)36 return Stringformat(s s greeting appName)37 38
39 GetMapping(hello)40 public String hello() 41 return Stringformat(Hello from s eurekaClientgetApplication(appName)
rarrgetName())42 43
236 参考
bull httpscloudspringiospring-cloud-netflixreferencehtml
bull httpswwwbaeldungcomspring-cloud-netflix-eureka
136 Chapter 23 Spring Cloud Eureka
CHAPTER 24
Spring Cloud Feign
241 介绍
Feign 是一个声明式的 Web Service 客户端它的目的就是让 Web Service 调用更加简单Feign 提供了HTTP 请求的模板通过编写简单的接口和注解就可以定义好 HTTP 请求的参数格式地址等信息Feign 会完全代理 HTTP 请求开发时只需要像调用方法一样调用它就可以完成服务请求及相关处理开源地址httpsgithubcomOpenFeignfeignFeign 整合了 Ribbon 负载和 Hystrix 熔断可以不再需要显式地使用这两个组件总体来说Feign 具有如下特性
bull 可插拔的注解支持包括 Feign 注解和 JAX-RS 注解
bull 支持可插拔的 HTTP 编码器和解码器
bull 支持 Hystrix 和它的 Fallback
bull 支持 Ribbon 的负载均衡
bull 支持 HTTP 请求和响应的压缩
Spring Cloud Feign 致力于处理客户端与服务器之间的调用需求简单来说使用 Spring Cloud Feign 组件他本身整合了 Ribbon 和 Hystrix可设计一套稳定可靠的弹性客户端调用方案避免整个系统出现雪崩效应
我们现在将使用 Spring Netflix Feign Client 实现一个使用 REST 的 Web 应用程序
将 Feign 视为 Spring RestTemplate 使用接口与 endpoints 进行通信该接口将在运行时自动实现而不是使用服务 URL 地址而是使用服务名称
137
Spring-Cloud Documentation 发布 10
242 依赖
设置 Feign Client 项目我们将在其 pomxml 中添加 spring-cloud-starter-feign 依赖
1 ltdependencygt2 ltgroupIdgtorgspringframeworkcloudltgroupIdgt3 ltartifactIdgtspring-cloud-starter-feignltartifactIdgt4 ltdependencygt
Feign客户端位于 spring-cloud-starter-feign软件包中要启用它我们必须使用 EnableFeignClients注解要使用它我们只需使用 FeignClient(ldquoservice-namerdquo)注解一个接口然后将其自动连接到控制器中即可
创建此类 Feign 客户端的一种好方法是使用 RequestMapping 注解方法创建接口并将其放入单独的模块中这样它们可以在服务器和客户端之间共享在服务器端可以将它们实现为 Controller而在客户端可以将其扩展和注解为 FeignClient
此外spring-cloud-starter-eureka 软件包需要包含在项目中并通过使用 EnableEurekaClient 注解主应用程序类来启用
243 Feign Client
如果没有 Feign我们将不得不将 EurekaClient 的一个实例自动连接到我们的控制器中通过该实例我们可以接收一个以 service-name 命名的服务信息作为 Application 对象根据此对象获取该服务的所有实例的列表选择一个合适的实例然后使用此实例获取主机名和端口这样我们可以对任何 http 客户端发出标准请求
下面的例子演示使用 Feign 访问 RestFul API
1 使用 EnableFeignClients 注解启用 Feign Client
1 package comibmtrainingdemo2
3 import orgspringframeworkbootSpringApplication4 import orgspringframeworkbootautoconfigureSpringBootApplication5 import orgspringframeworkcloudopenfeignEnableFeignClients6
7 EnableFeignClients8 SpringBootApplication9 public class DemoApplication
10
11 public static void main(String[] args) 12 SpringApplicationrun(DemoApplicationclass args)
(下页继续)
138 Chapter 24 Spring Cloud Feign
Spring-Cloud Documentation 发布 10
(续上页)
13 14
15
使用此注解我们扫描所有声明为 Feign 客户端的组件
2 使用 FeignClient 注解声明为 Feign 客户端
1 package comibmtrainingdemoclient2
3 import javautilList4
5 import orgspringframeworkcloudopenfeignFeignClient6 import orgspringframeworkwebbindannotationPathVariable7 import orgspringframeworkwebbindannotationRequestMapping8 import orgspringframeworkwebbindannotationRequestMethod9
10 import comibmtrainingdemomodelPost11
12 FeignClient(value = jplaceholder url = httpsjsonplaceholdertypicodecom)13 public interface JSONPlaceHolderClient 14
15 RequestMapping(method = RequestMethodGET value = posts)16 ListltPostgt getPosts()17
18 RequestMapping(method = RequestMethodGET value = postspostId produces =rarrapplicationjson)
19 Post getPostById(PathVariable(postId) Long postId)20
3 Post 类
1 package comibmtrainingdemomodel2
3 public class Post 4
5 private String userId6 private Long id7 private String title8 private String body9
(下页继续)
243 Feign Client 139
Spring-Cloud Documentation 发布 10
(续上页)
10 get 和 set 方法11
4 使用 JSONPlaceHolderClient
1 package comibmtrainingdemoservice2
3 import javautilList4
5 import orgspringframeworkbeansfactoryannotationAutowired6 import orgspringframeworkstereotypeService7
8 import comibmtrainingdemoclientJSONPlaceHolderClient9 import comibmtrainingdemomodelPost
10 import comibmtrainingdemoserviceJSONPlaceHolderService11
12 Service13 public class JSONPlaceHolderService14
15 Autowired16 private JSONPlaceHolderClient jsonPlaceHolderClient17
18 public ListltPostgt getPosts() 19 return jsonPlaceHolderClientgetPosts()20 21
22 public Post getPostById(Long id) 23 return jsonPlaceHolderClientgetPostById(id)24 25
244 自定义配置
Spring Cloud 为每个命名客户端创建一个默认 FeignClientsConfiguration 类的配置定义集根据需要我们可以自定义该类如下所述
上面的类包含以下 bean
Decoder ndash 解码器ResponseEntityDecoder包装 SpringDecoder用于解码 ResponseEncoder ndash 编码器SpringEncoder用于编码 RequestBody
(下页继续)
140 Chapter 24 Spring Cloud Feign
Spring-Cloud Documentation 发布 10
(续上页)
Logger ndash Slf4jLogger 是 Feign 使用的默认日志类Contract ndash SpringMvcContract提供注解处理Feign-Builder ndash HystrixFeignBuilder 用于构造组件Client ndash 客户端LoadBalancerFeignClient 或默认的 Feign 客户端
2441 自定义 Bean 配置
如果要自定义一个或多个这些 bean可以使用 Configuration类覆盖它们然后将其添加到 FeignClient注解中
1 package comibmtrainingdemoconfig2
3 import feignLogger4 import orgspringframeworkcontextannotationBean5 import orgspringframeworkcontextannotationConfiguration6
7 import feignRequestInterceptor8 import feigncodecErrorDecoder9 import feignformContentType
10 import feignokhttpOkHttpClient11
12 Configuration13 public class ClientConfiguration 14
15 Bean16 public LoggerLevel feignLoggerLevel() 17 return LoggerLevelFULL18 19
20 Bean21 public ErrorDecoder errorDecoder() 22 return new ErrorDecoderDefault()23 24
25 Bean26 public OkHttpClient client() 27 return new OkHttpClient()28 29
(下页继续)
244 自定义配置 141
Spring-Cloud Documentation 发布 10
(续上页)
30 Bean31 public RequestInterceptor requestInterceptor() 32 return requestTemplate -gt 33 requestTemplateheader(user murphy)34 requestTemplateheader(password abc123)35 requestTemplateheader(Accept ContentTypeURLENCODEDtoString())36 37 38
在此示例中我们告诉 Feign 使用 OkHttpClient 而不是默认值以便支持 HTTP2
Feign 支持针对不同用例的多个客户端包括 ApacheHttpClient该客户端随请求发送更多的 Header 头例如某些服务器期望的 Content-Length为了使用这些客户端请不要忘记将所需的依赖项添加到我们的pomxml 文件中例如
1 ltdependencygt2 ltgroupIdgtiogithubopenfeignltgroupIdgt3 ltartifactIdgtfeign-okhttpltartifactIdgt4 ltdependencygt5
6 ltdependencygt7 ltgroupIdgtiogithubopenfeignltgroupIdgt8 ltartifactIdgtfeign-httpclientltartifactIdgt9 ltdependencygt
2442 使用属性文件配置
2443 Interceptors
Feign 提供的另一个有用的功能是添加拦截器拦截器可以对每个 HTTP 请求响应执行从身份验证到日志记录的各种隐式任务
因此在下面的代码段中我们声明一个请求拦截器该拦截器将基本身份验证添加到每个请求
1 Bean2 public RequestInterceptor requestInterceptor() 3 return requestTemplate -gt 4 requestTemplateheader(user username)5 requestTemplateheader(password password)6 requestTemplateheader(Accept ContentTypeAPPLICATION_JSONgetMimeType())
(下页继续)
142 Chapter 24 Spring Cloud Feign
Spring-Cloud Documentation 发布 10
(续上页)
7 8
245 Feign with Eureka
上面的例子是单独介绍 Feign 的使用用的是 URL 的配置在 Eureka 中我们可以根据 name 来识别示例进而调用接口服务
1 参照教程中的 Spring Cloud Eureka 章节内容分别搭建好 Eureka server 和 Eureka Client 服务
2 搭建 spring-cloud-eureka-feign-client 示例具体代码如下
1 package comexampletrainingeurekafeigncontroller2
3 import orgspringframeworkcloudopenfeignFeignClient4 import orgspringframeworkwebbindannotationRequestMapping5
6 FeignClient(spring-cloud-eureka-client)7 public interface GreetingClient 8 RequestMapping(greeting)9 String greeting()
10
bull 这里使用 FeignClient 的 name 进行适配 Web API
bull 值rdquospring-cloud-eureka-clientrdquo对应 Eureka Client 实例中的 springapplicationname
1 package comexampletrainingeurekafeigncontroller2
3 import orgspringframeworkbeansfactoryannotationAutowired4 import orgspringframeworkcontextannotationLazy5 import orgspringframeworkwebbindannotationGetMapping6 import orgspringframeworkwebbindannotationRestController7
8 RestController9 public class GreetingController
10 Autowired11 Lazy12 private GreetingClient greetingClient13
14 GetMapping(get-greeting)(下页继续)
245 Feign with Eureka 143
Spring-Cloud Documentation 发布 10
(续上页)
15 public String greeting() 16 return greetingClientgreeting()17 18
19
bull 注入接口 GreetingClient然后调用它的方法
1 package comexampletrainingeurekafeign2
3 import orgspringframeworkbootSpringApplication4 import orgspringframeworkbootautoconfigureSpringBootApplication5 import orgspringframeworkcloudopenfeignEnableFeignClients6
7 SpringBootApplication8 EnableFeignClients9 public class TrainingEurekaFeignApplication
10
11 public static void main(String[] args) 12 SpringApplicationrun(TrainingEurekaFeignApplicationclass args)13 14
15
bull EnableFeignClients 这个注解的作用是启动 Feign Client
1 springapplicationname=spring-cloud-eureka-feign-client2 serverport=80803 eurekaclientserviceUrldefaultZone=$EUREKA_URIhttplocalhost8761eureka4
5 ribbonReadTimeout=50006 ribbonConnectTimeout=50007 ribbonMaxAutoRetries=08
9 infoappname=$springapplicationname
bull ribbon 的配置主要是解决 Feign timeout 的问题
3 成功部署后仪表板显示如下
144 Chapter 24 Spring Cloud Feign
Spring-Cloud Documentation 发布 10
4 浏览器中访问其中的 spring-cloud-eureka-feign-client 示例显示如下
2451 Hystrix
2452 Logging
2453 Error 处理
246 参考
bull httpswwwbaeldungcomspring-cloud-openfeign
246 参考 145
Spring-Cloud Documentation 发布 10
146 Chapter 24 Spring Cloud Feign
CHAPTER 25
Spring Cloud Zuul
251 Spring Cloud Zuul
Zuul 是 Spring Cloud Netflix 软件包的一部分并允许重定向 REST 请求以执行各种类型的过滤器
在几乎所有我们使用微服务的项目中都希望这些微服务之间的所有通信都经过一个公共场所以便记录输入和输出日志并可以根据各种参数来实现安全性或重定向请求
使用 Zuul 与 Spring Boot 非常容易实现
252 参考
httpsdzonecomarticlesredirecting-http-requests-with-zuul-in-spring-boot
147
Spring-Cloud Documentation 发布 10
148 Chapter 25 Spring Cloud Zuul
CHAPTER 26
ELK
261 Elasticsearch
262 Logstash
263 Kibana
264 参考
149
Spring-Cloud Documentation 发布 10
150 Chapter 26 ELK
CHAPTER 27
Assignment
271 Maven
2711 练习的目标
1 掌握在线构建 spring boot 项目
2 掌握 maven 环境仓库知识
3 掌握 maven 依赖关系
4 掌握 maven 执行周期
5 掌握 git 使用方法
6 掌握 spring boot 项目的基本功能
2712 练习的要求
1 Create a parent project with 3 submodules This app will consist of three modules that willrepresent
1 The core part of our domain
2 A web service providing some information from accessing RTC(IBM Rational Team Concert)
3 A webapp containing user-facing web assets of some sort
Parentrsquos pomxml file
151
Spring-Cloud Documentation 发布 10
1 ltmodulesgt2 ltmodulegtcoreltmodulegt3 ltmodulegtserviceltmodulegt4 ltmodulegtwebappltmodulegt5 ltmodulesgt
2 Building the Project
1 At least 1 unit test in each module
2 Run ldquomvn packagerdquosuccessful
3 Deploy the Project There is an area for displaying RTC information in webapp
4 Commit your assignment into github with gitignore
注解 注意 2 点 1 子 moudle 里面不能有 package plugin 2 web 里面的 application 的包路径需要在所有子 module 的包的父级
272 CRUD
CRUD(Create Read Update Delete)
2721 练习的目标
掌握 Spring Boot 项目基本的 CRUD 操作
2722 练习的要求
1 搭建 Spring Boot 项目开发环境添加依赖(Web Thymeleaf JPA H2)
2 实现进度表记录的展示添加修改和删除
1 修改默认端口
2 使用 Value 标签页面显示项目名称
3 创建 Entity(进度表)持久化到 H2 数据库项目启动时初始化数据
4 自定义错误页面
5 界面使用 Bootstrap(可选)
3 Commit your assignment into github with gitignore
4 部署到阿里云 (可选任何私有云)
152 Chapter 27 Assignment
Spring-Cloud Documentation 发布 10
参考httpswwwbaeldungcomspring-boot-start
272 CRUD 153
Spring-Cloud Documentation 发布 10
154 Chapter 27 Assignment
CHAPTER 28
Sphinx
281 Sphinx
2811 安装 Sphinx
bull httpwwwsphinx-docorgenmasterusageinstallationhtml
bull httpswwwsphinxorgcnusagequickstarthtml
2812 搭建 wiki
$ sphinx-quickstart
2813 主题
httpssphinx-themesorg
282 Wiki 语法
2821 gui
Cancel
155
Spring-Cloud Documentation 发布 10
Start rarr Programs
2019-12-03
LIFO (last-in first-out) (鼠标移上去出现提示文字)
guilabel`ampCancel`menuselection`Start --gt Programs`|today|abbr`LIFO (last-in first-out)`
today_fmt = Y-m-d B d Y
2822 code
所有支持的语言httppygmentsorglanguages
code-block ActionScriptemphasize-lines 34linenos
2823 note
参见
This is a simple seealso note
注解 This is a simple note note
待处理 This is a simple todo note need add this in confpy todo_include_todos=True
警告 This is a simple warning note include todo-tutorialmd
文字随便写
Extensions local to a project should be put within the projectrsquos directory structure Set Pythonrsquos modulesearch path syspath accordingly so that Sphinx can find them Eg if your extension foopy lies in theexts subdirectory of the project root put into confpy
156 Chapter 28 Sphinx
Spring-Cloud Documentation 发布 10
import sys ossyspathappend(ospathabspath(exts))extensions = [foo]
You can also install extensions anywhere else on syspath eg in the site-packages directory
seealso This is a simple seealso note
note This is a simple note note
todo This is a simple todo note need add this in confpy todo_include_rarrtodos=True warning This is a simple warning note include todo-tutorialmd
admonition 文字随便写
Extensions local to a project should be put within the projectrsquos directory structureSet Pythonrsquos module search path syspath accordingly so that Sphinx can find themEg if your extension foopy lies in the exts subdirectory of the project rootput into confpy
import sys ossyspathappend(ospathabspath(exts))extensions = [foo]
You can also install extensions anywhere else on syspath eg in the site-packagesrarrdirectory
2824 color
raw html
ltfont color=redgtRed wordltfontgt
2825 includefile
literalinclude _staticforms-ex600appappcomponenttslinenoslanguage typescriptlines 1 2-39
(下页继续)
282 Wiki 语法 157
Spring-Cloud Documentation 发布 10
(续上页)
code-block typescriptlinenos
thisformcontrols[make]valueChangessubscribe((value) =gt consolelog(value)
)thisformcontrols[make]statusChangessubscribe(
(value) =gt consolelog(value) )
include Applicationmd
2826 image
image imagesFigure19-7pngwidth 400pxalign centerheight 200pxalt alternate text
2827 table
The following table lists some useful lexers (in no particular order)
表 1 Frozen Delights
Treat Quantity DescriptionAlbatross 299 On a stickCrunchy Frog 149 If we took the bones out it wouldnrsquot be crunchy now
would itGannet Ripple 199 On a stick
158 Chapter 28 Sphinx
Spring-Cloud Documentation 发布 10
表 2 Frozen Delights
Treat Quantity DescriptionAlbatross 299 On a stickCrunchy Frog 149
If we took the bones out it wouldnrsquot be
crunchy now would it
Gannet Ripple 199 On a stick
csv-table Frozen Delightsheader Treat Quantity Descriptionwidths 15 10 30
Albatross 299 On a stickCrunchy Frog 149 If we took the bones out it wouldnt becrunchy now would itGannet Ripple 199 On a stick
list-table Frozen Delightswidths 15 10 30header-rows 1
- Treat- Quantity- Description
- Albatross- 299- On a stick
- Crunchy Frog- 149- If we took the bones out it wouldnt becrunchy now would it
- Gannet Ripple- 199- On a stick
282 Wiki 语法 159
Spring-Cloud Documentation 发布 10
2828 隐藏 source
html_show_sourcelink = False
2829 link
`link ltPython home page_gt`_
28210 Custom CSS
custom stylesheet is _staticcsscustomcss
confpy
These folders are copied to the documentations HTML outputhtml_static_path = [_static]
These paths are either relative to html_static_path or fully qualified paths (eg https)html_css_files = [
csscustomcss]
28211 chapters
及上划线表示部分 及上划线表示章节= 小章节- 子章节^ 子章节的子章节 段落
28212 highlight
The literal blocks are now highlighted as HTML until a new directive is found
160 Chapter 28 Sphinx
Spring-Cloud Documentation 发布 10
lthtmlgtltheadgtltheadgtltbodygtThis is a textltbodygtlthtmlgt
The following directive changes the hightlight language to SQL
SELECT FROM mytable
From here on no highlighting will be done
SELECT FROM mytable
28213 脚注
首先在正文中有个序号1 然后在页面的尾部 rubric 脚注
28214 Error
当执行 make html 命令时出现类似下面的错误信息时是由于根目录的权限不够导致的需要执行 chmod777 放开目录权限
reading sources [100] pagesnetflixlooking for now-outdated files none foundpickling environment donechecking consistency donepreparing documents WARNING search index couldnt be loaded but not all documentsrarrwill be built the index will be incompletedonewriting output [100] pagesnetflixgenerating indices genindexwriting additional pages search
283 部署到 github
1 在 github 上创建仓库根目录下新建文件夹 docs
2 拷贝 wiki 到 docs 目录下
3 提交代码1 演示脚注 include directive 点击左边的【1】迅速定位到上面的 脚注处
283 部署到 github 161
Spring-Cloud Documentation 发布 10
4 使用 github 账号登陆 Read the Docs 网站
5 选择导入的 github 上创建的仓库
6 按照步骤一步步操作最终 build 结果如下
162 Chapter 28 Sphinx
Spring-Cloud Documentation 发布 10
283 部署到 github 163
Spring-Cloud Documentation 发布 10
bull link httpsnestjsreadthedocsioenlatestindexhtml
bull demo httpsgithubcommurphylannest
284 参考
1 httpszh-sphinx-docreadthedocsioenlatestcontentshtml
2 syntax
3 Using_Sphinx
4 directives
5 httpsdocsreadthedocsioenstableindexhtml
任何文字(如脚注)
164 Chapter 28 Sphinx
CHAPTER 29
Spring Cloud Interview
291 问题集
httpswwwjavainusecomspringspring-cloud-interview-questions
Q What is Spring Cloud A Spring Cloud Stream App Starters are Spring Boot based Spring Integra-tion applications that provide integration with external systems Spring Cloud Task A short-livedmicroservices framework to quickly build applications that perform finite amounts of data processingSpring Cloud
Q What are the advantages of using Spring Cloud A When developing distributed microserviceswith Spring Boot we face the following issues-
bull Complexity associated with distributed systems- This overhead includes network issuesLatency overhead Bandwidth issues security issues
bull Service Discovery- Service discovery tools manage how processes and services in a cluster canfind and talk to one another It involves a directory of services registering services in thatdirectory and then being able to lookup and connect to services in that directory
bull Redundancy- Redundancy issues in distributed systems
bull Loadbalancing- Load balancing improves the distribution of workloads across multiple comput-ing resources such as computers a computer cluster network links central processing unitsor disk drives
bull Performance issues- Performance issues due to various operational overheads
165
Spring-Cloud Documentation 发布 10
bull Deployment complexities- Requirement of Devops skills
166 Chapter 29 Spring Cloud Interview
CHAPTER 30
Indices and tables
bull genindex
bull modindex
bull search
167
- Spring Boot Cloud 学习
-
- 课程进度
- 练习进度
-
- 初识 Maven
-
- Maven介绍
- 多线程
- 跳过测试
- 编译失败后接着编译
- 编译到最后再报错
- 使用 Nexus 本地私服
- 使用 Aliyun 国内镜像
- 指定 Repository 目录
- Maven Properties
- Maven Sources
- Maven Proxy
-
- 命令行设置
- 配置文件
-
- Dependency local Jar
- Install Jar
- MAVEN 属性
-
- 内置属性
- POM属性
- 自定义属性属性
- setting属性
- Java系统属性
- 环境变量属性
-
- MAVEN_OPTS
- Nexus Security
- Error in Eclipse
- 参考
-
- 初识 Git
-
- 常见Git命令
- Connecting with SSH
- RPC
-
- Web
- SSH
-
- API
-
- 初识 Docker
-
- 介绍
- Install
-
- Centos
- Install Docker Compose
-
- image and compose
- command
- 搭建 DB server
-
- docker-composeyml
- mongo-initsh
- startsh
-
- Issue
-
- Spring Boot CLI
-
- 安装Spring Boot CLI
-
- 从安装文件中手动安装
- 使用SDKMAN安装
- 利用OSX Homebrew安装
- 使用MacPorts安装
-
- 开始使用CLI
- 使用CLI初始化项目
- 参考
-
- Spring Boot 2x 学习
-
- Spring Boot 概述
- 常规概念
-
- PO
- BO
- VO
- POJO
- DTO
- DAO
-
- 快速上手
-
- 在线界面初始化项目
- 环境准备
- pomxml
- 添加Code
- 运行程序
-
- IDE中执行
- mvn执行
-
- 创建 an Executable Jar
- 部署
-
- 参考
-
- Spring Boot Controller
-
- 理解 Controller
- 实现REST服务
- ResponseEntity
- RequestMapping
- Controller中获取参数
-
- Controller方法的形参
- HttpServletRequest
- 通过Bean接收
- PathVariable
- ModelAttribute
- RequestParam
- RequestBody
- RequestHeader CookieValue
-
- Spring Boot Service