Compare commits
	
		
			10 Commits
		
	
	
		
			ea0f7676cd
			...
			d29c289119
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					d29c289119 | ||
| 
						 | 
					e0bd5dadfe | ||
| 
						 | 
					8c4d134dad | ||
| 
						 | 
					f11d7d976b | ||
| 
						 | 
					4261aad6a0 | ||
| 
						 | 
					326d7a050a | ||
| 
						 | 
					3a00e7c51b | ||
| 
						 | 
					95e3144f7e | ||
| 
						 | 
					296acd792b | ||
| 
						 | 
					4a0dfb534c | 
@@ -95,3 +95,12 @@ spring-cloud:Finchley.SR2
 | 
			
		||||
 | 
			
		||||
- Servlet3.1 规范(最终版).pdf
 | 
			
		||||
- Thymeleaf 中⽂参考⼿册.pdf
 | 
			
		||||
 | 
			
		||||
<br>
 | 
			
		||||
 | 
			
		||||
<div align="center">
 | 
			
		||||
	<a href = "https://blog.csdn.net/m0_37809146"> 
 | 
			
		||||
	<img width="200px" src="https://gitee.com/heibaiying/BigData-Notes/raw/master/pictures/blog-logo.png"/> 
 | 
			
		||||
	</a> 
 | 
			
		||||
</div>
 | 
			
		||||
<div align="center"> <a  href = "https://blog.csdn.net/m0_37809146"> 欢迎关注我的博客:https://blog.csdn.net/m0_37809146</a> </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
 | 
			
		||||
## 一、项目结构
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-session.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-session.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 二、实现分布式 Session
 | 
			
		||||
@@ -151,13 +151,13 @@ Session 信息展示页面 home.ftl:
 | 
			
		||||
 | 
			
		||||
应用 1 启动配置:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-session-app1.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-session-app1.png"/> </div>
 | 
			
		||||
 | 
			
		||||
应用 2 启动配置,需要用 `--server.port ` 指定不同的端口号:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-session-app2.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-session-app2.png"/> </div>
 | 
			
		||||
 | 
			
		||||
**测试结果:**
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-session-8080.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-session-8090.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-session-8080.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-session-8090.png"/> </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
 | 
			
		||||
分布式 Session 主要配置文件为 spring-session.xml 和 web.xml,其他的配置为标准的 web 工程的配置:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-session.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-session.png"/> </div>
 | 
			
		||||
 | 
			
		||||
## 二、实现分布式 Session
 | 
			
		||||
 | 
			
		||||
@@ -188,13 +188,13 @@ session 信息展示页面 (home.jsp):
 | 
			
		||||
 | 
			
		||||
Tomcat 1 配置:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-session-tomcat01.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-session-tomcat01.png"/> </div>
 | 
			
		||||
 | 
			
		||||
Tomcat 2 配置:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-session-tomcat02.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-session-tomcat02.png"/> </div>
 | 
			
		||||
 | 
			
		||||
**测试结果:**
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-session-8080.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-session-8090.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-session-8080.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-session-8090.png"/> </div>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								pictures/blog-logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								pictures/blog-logo.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 37 KiB  | 
@@ -125,7 +125,7 @@ health 端点用于暴露程序运行的健康状态,暴露的信息的详细
 | 
			
		||||
- **CustomHealthAggregator**:自定义健康状态聚合规则;
 | 
			
		||||
- **CustomEndPoint**:自定义端点。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-actuator.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-actuator.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 2.2 主要依赖
 | 
			
		||||
 | 
			
		||||
@@ -160,7 +160,7 @@ management:
 | 
			
		||||
 | 
			
		||||
导入 Actuator 的 starter 并进行配置后,访问 http://127.0.0.1:8080/actuator/health 就可以看到对应的项目监控状态。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/health.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/health.png"/> </div>
 | 
			
		||||
 | 
			
		||||
健康指标 HealthIndicators 由 Spring Boot 自动配置,因此这里显示监控信息是由项目所使用的技术栈而决定的:
 | 
			
		||||
 | 
			
		||||
@@ -207,11 +207,11 @@ public class CustomHealthIndicator implements HealthIndicator {
 | 
			
		||||
 | 
			
		||||
自定义检查通过的情况下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/actuator-health-up.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/actuator-health-up.png"/> </div>
 | 
			
		||||
 | 
			
		||||
自定义检查失败的情况:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/health-fatal-200.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/health-fatal-200.png"/> </div>
 | 
			
		||||
 | 
			
		||||
自定义检查不论是否通过都不会影响整体的 status,因此两种情况下的 status 值都是 `up`。如果想通过自定义检查去影响整体的检查结果,比如健康检查针对的是支付业务,在支付业务的不可用的情况下,我们就应该认为整个服务是不可用的,这个时候就需要通过自定义健康状态的聚合规则来实现。
 | 
			
		||||
 | 
			
		||||
@@ -241,7 +241,7 @@ public class CustomHealthAggregator implements HealthAggregator {
 | 
			
		||||
 | 
			
		||||
当我们自定义健康检查项不通过时候的结果如下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/actuator-heath-503.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/actuator-heath-503.png"/> </div>
 | 
			
		||||
 | 
			
		||||
这里需要注意的是返回自定义的聚合状态时,状态码也变成了 503,这是我们在配置文件中进行定义的:
 | 
			
		||||
 | 
			
		||||
@@ -319,8 +319,8 @@ public class CustomEndPoint {
 | 
			
		||||
 | 
			
		||||
地址为:http://127.0.0.1:8080/actuator/customEndPoint :
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/actuator-customEndPoint.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/actuator-customEndPoint.png"/> </div>
 | 
			
		||||
 | 
			
		||||
关于 Sigar 的更多监控参数可以参考博客:[java 读取计算机 CPU、内存等信息(Sigar 使用)](https://blog.csdn.net/wudiazu/article/details/73829324) 或 Sigar 下载包中的用例:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/sigar.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/sigar.png"/> </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
2. 模板引擎采用 freemaker 和 thymeleaf 作为示例,分别对应模板文件 makershow.ftl 和 leafShow.html;
 | 
			
		||||
3. Spring Boot 2.x 默认不支持 Jsp ,需要额外的配置,关于使用 jsp 的整合可以参考 [spring-boot-jsp](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-jsp) 项目。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-base.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-base.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 | 
			
		||||
@@ -93,7 +93,7 @@
 | 
			
		||||
 | 
			
		||||
+ Spring Boot 项目默认继承自 spring-boot-starter-parent,而 spring-boot-starter-parent 则继承自 spring-boot-dependencies,spring-boot-dependencies 中定义了关于 spring boot 依赖的各种 jar 包的版本,它是 Spring Boot 的版本管理中心。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-dependencies.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-dependencies.png"/> </div>
 | 
			
		||||
 | 
			
		||||
+ 关于Spring Boot 2.x 官方支持的所有 starter 可以参见官方文档:[Table 13.1. Spring Boot application starters](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#using-boot-starter)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
 | 
			
		||||
### 1.1 项目结构
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-data-jpa.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-data-jpa.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
 | 
			
		||||
2. 为了演示 Druid 控制台的功能,项目以 Web 的方式构建。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-druid-mybatis.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-druid-mybatis.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 | 
			
		||||
@@ -199,10 +199,10 @@ public class DruidStatController {
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/druid-status.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/druid-status.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 2.4 Druid 控制台
 | 
			
		||||
 | 
			
		||||
默认访问地址为 http://localhost:8080/druid/login.html :
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-druid%20%E6%8E%A7%E5%88%B6%E5%8F%B0.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-druid%20%E6%8E%A7%E5%88%B6%E5%8F%B0.png"/> </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
- **boot-dubbo-provider** :服务的提供者,提供商品的查询服务;
 | 
			
		||||
- **boot-dubbo-consumer** :是服务的消费者,调用 provider 提供的查询服务。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-dubbo.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-dubbo.png"/> </div>
 | 
			
		||||
 | 
			
		||||
## 二、基本依赖
 | 
			
		||||
 | 
			
		||||
@@ -101,11 +101,11 @@
 | 
			
		||||
- api 下为公共的调用接口;
 | 
			
		||||
- bean 下为公共的实体类。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/boot-dubbo-common.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/boot-dubbo-common.png"/> </div>
 | 
			
		||||
 | 
			
		||||
## 四、服务提供者
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/boot-dubbo-provider.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/boot-dubbo-provider.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 4.1 提供者配置
 | 
			
		||||
 | 
			
		||||
@@ -160,7 +160,7 @@ public class ProductService implements IProductService {
 | 
			
		||||
 | 
			
		||||
## 五、服务消费者
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/boot-dubbo-consumer1.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/boot-dubbo-consumer1.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 5.1 消费者配置
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
</nav>
 | 
			
		||||
 | 
			
		||||
## 一、项目说明
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-jsp.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-kafka.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-kafka.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2 主要依赖
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ Spring 官方并没有提供关于 Memcached 的 starter,所以我们还是采
 | 
			
		||||
 | 
			
		||||
Memcached 的整合配置位于 config 文件夹下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-memcached.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-memcached.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.3 基本依赖
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
- 提供基于 MongoTemplate 的方式操作 MongoDB,见测试用例 MongoOriginalTests;
 | 
			
		||||
- 提供基于 Spring Data JPA   的方式操作 MongoDB (推荐),见测试用例 MongoJPATests。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-mongodb.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-mongodb.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
 | 
			
		||||
   **注解写法**:对应的类为 Programmer.java ,用 MybatisAnnotationTest 进行测试。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-mybatis.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-mybatis.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2 主要依赖
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
- **rabbitmq-producer** :消息的生产者模块;
 | 
			
		||||
- **rabbitmq-consumer** :是消息的消费者模块。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-rabbitmq.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-rabbitmq.png"/> </div>
 | 
			
		||||
 | 
			
		||||
## 二、主要依赖
 | 
			
		||||
 | 
			
		||||
@@ -91,7 +91,7 @@
 | 
			
		||||
- bean 下为公共的实体类。
 | 
			
		||||
- constant 下为公共配置,用静态常量进行引用。这里我使用静态常量是为了方便引用,实际中也可以按照情况,抽取为公共的配置文件。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/rabbitmq-common.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/rabbitmq-common.png"/> </div>
 | 
			
		||||
```java
 | 
			
		||||
public class RabbitInfo {
 | 
			
		||||
 | 
			
		||||
@@ -113,7 +113,7 @@ public class RabbitInfo {
 | 
			
		||||
 | 
			
		||||
## 四、消息消费者
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/rabbitmq-consumer.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/rabbitmq-consumer.png"/> </div>
 | 
			
		||||
### 4.1 消费者配置
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
@@ -186,7 +186,7 @@ public class RabbitmqConsumer {
 | 
			
		||||
 | 
			
		||||
## 五、消息生产者
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/rabbitmq-producer.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/rabbitmq-producer.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 5.1 生产者配置
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
- RedisConfig.java 实现了 redisTemplate 序列化与反序列化的配置;
 | 
			
		||||
- RedisOperation 和 RedisObjectOperation 分别封装了对基本类型和对象的操作。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-redis.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-redis.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
- Servlet、过滤器、监听器分别位于 servlet、filter、listen 下,其中以 Annotation 命名结尾的代表是 Servlet 是以注解方式实现,采用 Spring 注册方式则需要在 ServletConfig 中进行注册;
 | 
			
		||||
- 为了说明外置容器对 Servlet 注解的自动发现机制,项目采用外置容器构建,关于 Spring Boot 整合外置容器的详细说明可以参考:[spring-boot-tomcat](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-boot/spring-boot-tomcat) 。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-servlet.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-servlet.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2 项目依赖
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ Swagger 是一个规范框架,用于生成、描述、调用和可视化 RESTf
 | 
			
		||||
 | 
			
		||||
下图为 swagger-ui 提供的文档可视化界面示例:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/Swagger_UI.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/Swagger_UI.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.3 关联关系
 | 
			
		||||
@@ -243,16 +243,16 @@ Swagger 为了最大程度防止对逻辑代码的侵入,基本都是依靠注
 | 
			
		||||
 | 
			
		||||
接口文档访问地址:http://localhost:8080/swagger-ui.html ,文档主界面如下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/swagger-ui-index.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/swagger-ui-index.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 2.5 接口测试
 | 
			
		||||
 | 
			
		||||
Swagger-UI 除了提供接口可视化的功能外,还可以用于接口测试。点击对应接口的 `try it out` 按钮,然后输入对应的参数的值,最后点击下方的 `Execute` 按钮发送请求:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/swagger-try-it.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/swagger-try-it.png"/> </div>
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/swagger-execute.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/swagger-execute.png"/> </div>
 | 
			
		||||
 | 
			
		||||
POST 接口可以直接修改 Model 对应的 Json 数据 ,然后点击下方的 `Execute` 按钮发送请求:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/swagger-post-try.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/swagger-post-try.png"/> </div>
 | 
			
		||||
 
 | 
			
		||||
@@ -16,11 +16,14 @@
 | 
			
		||||
 | 
			
		||||
Spring Boot 默认采用内置的 Web 容器,因此打成 JAR 包后就可以直接运行。但在某的时候,你可能还是需要使用 Tomcat 来运行和管理 Web 项目,因此本用例主要介绍 Spring Boot 与 Tomcat 的整合方式。另外 Spring Boot 内置的 Web 容器默认并不支持 JSP,所以可以使用跳转到 JSP 页面的方式来测试整合外部容器是否成功。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-tomcat.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-tomcat.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 | 
			
		||||
```xml
 | 
			
		||||
<!--指定打包方式--> 
 | 
			
		||||
<packaging>war</packaging>
 | 
			
		||||
 | 
			
		||||
<dependency>
 | 
			
		||||
    <groupId>org.springframework.boot</groupId>
 | 
			
		||||
    <artifactId>spring-boot-starter-web</artifactId>
 | 
			
		||||
@@ -39,6 +42,19 @@ Spring Boot 默认采用内置的 Web 容器,因此打成 JAR 包后就可以
 | 
			
		||||
    <version>2.5</version>
 | 
			
		||||
    <scope>provided</scope>
 | 
			
		||||
</dependency>
 | 
			
		||||
 | 
			
		||||
<build>
 | 
			
		||||
    <plugins>
 | 
			
		||||
        <plugin>
 | 
			
		||||
            <groupId>org.apache.maven.plugins</groupId>
 | 
			
		||||
            <artifactId>maven-war-plugin</artifactId>
 | 
			
		||||
            <configuration>
 | 
			
		||||
                <!--不需要检查web.xml是否存在-->
 | 
			
		||||
                <failOnMissingWebXml>false</failOnMissingWebXml>
 | 
			
		||||
            </configuration>
 | 
			
		||||
        </plugin>
 | 
			
		||||
    </plugins>
 | 
			
		||||
</build>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 二、整合 Tomcat
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
    <version>0.0.1-SNAPSHOT</version>
 | 
			
		||||
    <name>spring-boot-tomcat</name>
 | 
			
		||||
    <description>boot-tomcat project for Spring Boot</description>
 | 
			
		||||
    <packaging>war</packaging>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
        <java.version>1.8</java.version>
 | 
			
		||||
@@ -57,6 +58,13 @@
 | 
			
		||||
                <groupId>org.springframework.boot</groupId>
 | 
			
		||||
                <artifactId>spring-boot-maven-plugin</artifactId>
 | 
			
		||||
            </plugin>
 | 
			
		||||
            <plugin>
 | 
			
		||||
                <groupId>org.apache.maven.plugins</groupId>
 | 
			
		||||
                <artifactId>maven-war-plugin</artifactId>
 | 
			
		||||
                <configuration>
 | 
			
		||||
                    <failOnMissingWebXml>false</failOnMissingWebXml>
 | 
			
		||||
                </configuration>
 | 
			
		||||
            </plugin>
 | 
			
		||||
        </plugins>
 | 
			
		||||
    </build>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
- 关于 WebSocket 的主要配置在 websocket 文件夹下;
 | 
			
		||||
- 模板引擎采用 freemaker;
 | 
			
		||||
- 项目以 Web 的方式构建。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-websocket.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
 | 
			
		||||
## 一、项目结构
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-boot-yml-profile.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-boot-yml-profile.png"/> </div>
 | 
			
		||||
 | 
			
		||||
## 二、YAML 语法
 | 
			
		||||
 | 
			
		||||
@@ -149,7 +149,7 @@ Spring Boot 在将环境属性绑定到 `@ConfigurationProperties` beans 时会
 | 
			
		||||
 | 
			
		||||
可以在同一个 yml 文件中包含多个配置文件,并使用 `---` 进行分割。或者遵循 application-xxx.yml 命名方式来为不同的环境(如开发环境,生产环境,测试环境)分别生成不同的配置文件,然后再在主配置文件 application.yml 中来决定使用哪个具体的配置,或在启动时候通过命令行参数来决定,命令行的优先级大于配置文件的优先级。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/profile.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/profile.png"/> </div>
 | 
			
		||||
 | 
			
		||||
```yaml
 | 
			
		||||
# 配置文件中激活开发环境配置
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@
 | 
			
		||||
 | 
			
		||||
主要配置如下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/springboot-druid-mybatis-multi.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/springboot-druid-mybatis-multi.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -474,7 +474,7 @@ public class XATransactionManagerConfig {
 | 
			
		||||
 | 
			
		||||
这里我一共给了三种情况的测试接口,如下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/springboot-druid-mybatis-multi-test.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/springboot-druid-mybatis-multi-test.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 3.1  测试数据库整合结果
 | 
			
		||||
 | 
			
		||||
@@ -482,15 +482,15 @@ public class XATransactionManagerConfig {
 | 
			
		||||
 | 
			
		||||
mysql 数据库:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/mysql01.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/mysql01.png"/> </div>
 | 
			
		||||
 | 
			
		||||
mysql02 数据库:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/mysql02.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/mysql02.png"/> </div>
 | 
			
		||||
 | 
			
		||||
**前端查询结果**:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/mysql0102.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/mysql0102.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 3.2 测试单数据库事务
 | 
			
		||||
 | 
			
		||||
@@ -571,19 +571,19 @@ public class XATransactionController {
 | 
			
		||||
 | 
			
		||||
数据源 1:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/druid-mysql01.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/druid-mysql01.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
数据源 2:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/durud-mysql02.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/durud-mysql02.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
url 监控情况:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/durid-mysql-weburl.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/durid-mysql-weburl.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -599,7 +599,7 @@ XA 是由 X/Open 组织提出的分布式事务的规范。XA 规范主要定义
 | 
			
		||||
 | 
			
		||||
**而 JTA 就是 XA 规范在 java 语言上的实现。JTA 采用两阶段提交实现分布式事务。**
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/XA.gif"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/XA.gif"/> </div>
 | 
			
		||||
 | 
			
		||||
### 4.2 两阶段提交
 | 
			
		||||
 | 
			
		||||
@@ -614,7 +614,7 @@ XA 是由 X/Open 组织提出的分布式事务的规范。XA 规范主要定义
 | 
			
		||||
 | 
			
		||||
在一个分布式事务中,必须有一个场地的 Server 作为协调者 (coordinator),它能向  其它场地的 Server 发出请求,并对它们的回答作出响应,由它来控制一个分布式事务的提交或撤消。该分布式事务中涉及到的其它场地的 Server 称为参与者 (Participant)。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/commit.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/commit.png"/> </div>
 | 
			
		||||
 | 
			
		||||
事务两阶段提交的过程如下:
 | 
			
		||||
 | 
			
		||||
@@ -655,7 +655,7 @@ XA 是由 X/Open 组织提出的分布式事务的规范。XA 规范主要定义
 | 
			
		||||
> sqlSessionTemplate 与 Spring 事务管理一起使用,以确保使用的实际 SqlSession 是与当前 Spring 事务关联的,此外它还管理会话生命周期,包括根据 Spring 事务配置根据需要关闭,提交或回滚会话。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/sqlSessionTemplate.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/sqlSessionTemplate.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
这里最主要的是说明 SqlSession 是与当前是 Spring 事务是关联的。
 | 
			
		||||
@@ -737,31 +737,31 @@ public static Connection doGetConnection(DataSource dataSource) throws SQLExcept
 | 
			
		||||
这里主要的问题是 `TransactionSynchronizationManager.getResource(dataSource)` 中 dataSource 参数是在哪里进行注入的,这里可以沿着调用堆栈往上寻找,可以看到是在这个参数是 `SpringManagedTransaction` 类中获取连接的时候传入的。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/opneConnection.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/opneConnection.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
而 `SpringManagedTransaction` 这类中的 dataSource 是如何得到赋值的,这里可以进入这个类中查看,只有在创建这个类的时候通过构造器为 dataSource 赋值,那么是哪个方法创建了 `SpringManagedTransaction`?
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/springManagerTransaction.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/springManagerTransaction.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
在构造器上打一个断点,沿着调用的堆栈往上寻找可以看到是 `DefaultSqlSessionFactory` 在创建 `SpringManagedTransaction` 中传入的,**这个数据源就是创建 sqlSession 的 `sqlSessionFactory` 中数据源**。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/DefaultSqlSessionFactory.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/DefaultSqlSessionFactory.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**这里说明连接的复用是与我们创建 SqlSession 时候传入的 SqlSessionFactory 是否是同一个有关**。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/getsqlSession.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/getsqlSession.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
所以我们才重写了 SqlSessionTemplate 中的 `getSqlSession` 方法,获取 SqlSession 时候传入正在使用的数据源对应的 `SqlSessionFactory`,这样即便在同一个的事务中,由于传入的 `SqlSessionFactory` 中不同,就不会出现连接复用。
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/customSqlSessionTemplate.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/customSqlSessionTemplate.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
关于 Mybati-Spring 的更多事务处理机制,推荐阅读博客:[mybatis-spring 事务处理机制分析](https://my.oschina.net/fifadxj/blog/785621)
 | 
			
		||||
@@ -800,7 +800,7 @@ private SqlSessionFactory createSqlSessionFactory(DataSource dataSource) throws
 | 
			
		||||
 | 
			
		||||
正常绑定的情况下,我们是可以在 SqlSessionFactory 中查看到绑定好的查询接口:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/sqlSessionFactory.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/sqlSessionFactory.png"/> </div>
 | 
			
		||||
<br>
 | 
			
		||||
 | 
			
		||||
## 参考资料
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ Spring Cloud Config 分为服务端和客户端,服务端称为分布式配置
 | 
			
		||||
+ **config-client**:服务单元,可以从配置中心获取相关配置;
 | 
			
		||||
+ **eureka**:注册中心。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-config.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-config.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -147,20 +147,20 @@ spring:
 | 
			
		||||
- **application.yml** :为主配置;
 | 
			
		||||
- **application-dev.yml**:为开发环境配置。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/config-git.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/config-git.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 3.4   启动服务
 | 
			
		||||
 | 
			
		||||
启动 Eureka 和 Config-Server 服务,访问 http://localhost:8020/application-dev.yml  , 此时界面如下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/config-application-dev.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/config-application-dev.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
注意此时我们访问是 dev 分支,即开发环境配置,其实际的配置文件的内容如下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/config-dev.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/config-dev.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -180,7 +180,7 @@ spring:
 | 
			
		||||
 | 
			
		||||
其中 application 为配置文件名,profile 为环境,label 为分支(如果不指定默认就是 master 分支)。从上面的规则中我们可以看出并不存在单独的 `/{application}` 访问路径,所以必须接上一个任意字符,示例如下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/config-a.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/config-a.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -323,7 +323,7 @@ public class ConfigController {
 | 
			
		||||
 | 
			
		||||
依次启动 eureka,config-server,config-client 三个项目,访问 http://localhost:8030/programmer 。在启动 eureka 和 config-server 后,要稍等一会再启动 config-client,这里是为了确保 config-server 已经将服务注册到 Eureka,然后我们的 config-client 才能从 Eureka 中获取配置中心的服务:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/config-client-programmer.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/config-client-programmer.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
启动时可以从控制台上看到拉取配置的相关信息:
 | 
			
		||||
@@ -442,10 +442,10 @@ o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-de
 | 
			
		||||
 | 
			
		||||
也可以在 RabbitMQ 管控台上查看:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-bus-exchange.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-bus-exchange.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-bus-queue.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-bus-queue.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -453,7 +453,7 @@ o.s.amqp.rabbit.core.RabbitAdmin         : Auto-declaring a non-durable, auto-de
 | 
			
		||||
 | 
			
		||||
 直接在 Git 上修改配置文件,然后用 `post` 请求触发热刷新端点 http://localhost:8030/actuator/bus-refresh ,即可看到配置已经热刷新。注意这里的只能用 post 方式请求 ,你可以用 Postman 等测试软件来发送:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/bus-refresh.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/bus-refresh.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
- **eureka-server** 为服务注册中心,负责服务的管理;
 | 
			
		||||
- **eureka-client** 为 Eureka 客户端。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-eureka-cluster.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-eureka-cluster.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -30,7 +30,7 @@
 | 
			
		||||
 | 
			
		||||
这里我们以单机伪集群的方式搭建,让三个单机注册中心互相注册,实现注册中心的高可用。配置示意图如下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/eureka-server-client.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/eureka-server-client.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 2.1 服务端依赖
 | 
			
		||||
@@ -46,7 +46,7 @@
 | 
			
		||||
 | 
			
		||||
创建三份配置文件,分别代表不同注册中心的配置:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/eureka-application.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/eureka-application.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
application-01.yml:
 | 
			
		||||
@@ -175,7 +175,7 @@ public class EurekaClientApplication {
 | 
			
		||||
 | 
			
		||||
这里我们可以采用命令行方式指定配置,分别启动三个注册中心:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/eureka-active.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/eureka-active.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 4.2  集群搭建成功的判定
 | 
			
		||||
@@ -184,17 +184,17 @@ public class EurekaClientApplication {
 | 
			
		||||
 | 
			
		||||
8010 注册中心:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/eureka-8010.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/eureka-8010.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
8020 注册中心:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/eureka-8020.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/eureka-8020.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
8030 注册中心:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/eureka-8030.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/eureka-8030.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Status 下的每个注册中心都可以点击跳转到其监控页面,但其监控页面地址链接可能是动态变化的,主要情况如下:
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ Spring Cloud Eureka 使用 Netflix Eureka 来实现服务注册与发现,它
 | 
			
		||||
- **eureka-server** 为服务注册中心,负责服务的管理;
 | 
			
		||||
- **eureka-client** 为 Eureka 客户端。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-eureka.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-eureka.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -127,6 +127,6 @@ public class EurekaClientApplication {
 | 
			
		||||
 | 
			
		||||
进入注册中心控制台,查看服务注册情况:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/eureka.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/eureka.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@
 | 
			
		||||
+ **producer**:服务的提供者;
 | 
			
		||||
+ **eureka**:注册中心。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-feign.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-feign.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -45,7 +45,7 @@
 | 
			
		||||
 | 
			
		||||
## 三、服务提供者的实现
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/feign-producer.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/feign-producer.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 3.1 定义服务
 | 
			
		||||
@@ -149,7 +149,7 @@ public class ProducerApplication {
 | 
			
		||||
 | 
			
		||||
## 四、服务消费者的实现
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/feign-consumer.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/feign-consumer.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 4.1 基本依赖
 | 
			
		||||
@@ -221,7 +221,7 @@ public interface ProductFeign {
 | 
			
		||||
 | 
			
		||||
按照官方对于服务最佳化的推荐,这里我们的服务调用接口放在公共模块中,因为在实际的开发中,同一个服务调用接口可能被多个模块所使用。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/common-feign.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/common-feign.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -285,25 +285,25 @@ public class SellController {
 | 
			
		||||
 | 
			
		||||
启动一个Eureka服务、三个生产者服务(注意区分端口)、和一个消费者服务。Feign 的依赖中导入了 spring-cloud-starter-netflix-ribbon 依赖,并且在内部实现了基于 Ribbon 的客户端负载均衡,所以我们这里启动三个生产者服务来观察负载均衡的情况:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-ribbon-app.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-ribbon-app.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**服务注册中心:**
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-ribbon-eureka.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-ribbon-eureka.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 5.2  验证负载均衡
 | 
			
		||||
 | 
			
		||||
访问 http://localhost:8080/sell/products 查看负载均衡的调用结果:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-ribbon-products-8020.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-ribbon-products-8020.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-ribbon-products-8030.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-ribbon-products-8030.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/feign-8040.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/feign-8040.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -316,7 +316,7 @@ public class SellController {
 | 
			
		||||
 | 
			
		||||
Feign 的依赖中默认导入了 Hystrix (熔断器)的相关依赖,我们不需要额外导入,只需要开启相关配置即可:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/feign-hystrix-maven.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/feign-hystrix-maven.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -422,6 +422,6 @@ public List<Product> queryAllProducts() {
 | 
			
		||||
 | 
			
		||||
测试结果:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/feign-hystrix.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/feign-hystrix.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@
 | 
			
		||||
- 当一个服务处理请求失败的次数大于阈值时,熔断器开启,这时所有的请求都会执行快速失败,而不会去调用实际的服务;
 | 
			
		||||
- 当熔断器处于打开状态的一段时间后,熔断器处于半打开状态,这时候一定数量的请求回去调用实际的服务,如果调用成功,则代表服务可用了,熔断器关闭;如果还是失败,则代表服务还是不可用,熔断器继续打开。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/circuitbreaker.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/circuitbreaker.png"/> </div>
 | 
			
		||||
 | 
			
		||||
## 二、项目结构
 | 
			
		||||
 | 
			
		||||
@@ -49,7 +49,7 @@
 | 
			
		||||
+ **eureka**: 注册中心;
 | 
			
		||||
+ **turbine**:多个熔断器的聚合监控。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-hystrix.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-hystrix.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 三、整合 Hystrix 
 | 
			
		||||
@@ -172,7 +172,7 @@ public List<Product> queryAllProducts() {
 | 
			
		||||
 | 
			
		||||
启动服务,访问 http://localhost:8030/sell/products ,多次刷新查看熔断情况:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/hystrix-8030.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/hystrix-8030.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 3.7 控制台
 | 
			
		||||
 | 
			
		||||
@@ -182,15 +182,15 @@ public List<Product> queryAllProducts() {
 | 
			
		||||
 | 
			
		||||
**登录页面**:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/hystrix-single-login.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/hystrix-single-login.png"/> </div>
 | 
			
		||||
 | 
			
		||||
**监控页面**:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/hystrix-8030-login.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/hystrix-8030-login.png"/> </div>
 | 
			
		||||
 | 
			
		||||
**关于各个参数的说明参见[官方 wiki](https://github.com/Netflix-Skunkworks/hystrix-dashboard/wiki) 提供的图**:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/dashboard.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/dashboard.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -199,7 +199,7 @@ public List<Product> queryAllProducts() {
 | 
			
		||||
 | 
			
		||||
如果你想要聚合监控不同服务单元下的多个断路器,可以使用 Turbine 来实现。单体监控和聚合监控的区别如下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/dashboard-direct-vs-turbine-640.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/dashboard-direct-vs-turbine-640.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 4.1 导入依赖
 | 
			
		||||
@@ -311,11 +311,11 @@ public class TurbineApplication {
 | 
			
		||||
 | 
			
		||||
依次启动 eureka、producer、consumer、turbine 四个项目,因为 consumer 和 producer 都集成了 Hystrix ,所以可以在 localhost:8020/hystrix 或者 8030/hystrix 页面输入 http://localhost:8040/turbine.stream  来查看断路器聚合信息:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/hystrix-cluster-login.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/hystrix-cluster-login.png"/> </div>
 | 
			
		||||
 | 
			
		||||
**显示了不同服务单元(consumer,producer)的多个断路器信息:**
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/hystrix-cluster.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/hystrix-cluster.png"/> </div>
 | 
			
		||||
 | 
			
		||||
## 五、常见问题
 | 
			
		||||
 | 
			
		||||
@@ -354,5 +354,5 @@ public ServletRegistrationBean getServlet() {
 | 
			
		||||
 | 
			
		||||
这种情况是熔断器所在的方法没有被调用,所以没有产生监控数据,不是整合问题,这时候调用一下熔断器所在方法即可:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/hystrix-loading.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/hystrix-loading.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ Ribbon 是 Netfix 公司开源的负载均衡组件,采用服务端负载均
 | 
			
		||||
+ **producer**:服务的提供者;
 | 
			
		||||
+ **eureka**:注册中心,Ribbon 从注册中心获取可用的服务列表,是实现负载均衡的基础。这里使用我们在 [服务的注册与发现](https://github.com/heibaiying/spring-samples-for-all/tree/master/spring-cloud/spring-cloud-eureka) 这个用例中搭建的注册中心即可。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-ribbon.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-ribbon.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 三、服务提供者的实现
 | 
			
		||||
@@ -45,7 +45,7 @@ Ribbon 是 Netfix 公司开源的负载均衡组件,采用服务端负载均
 | 
			
		||||
 | 
			
		||||
 产品服务由 `ProductService` 提供,并通过 `ProducerController` 将服务暴露给外部调用:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/ribbon-producer.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/ribbon-producer.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ProductService.java:
 | 
			
		||||
@@ -150,7 +150,7 @@ public class ProducerApplication {
 | 
			
		||||
 | 
			
		||||
## 四、服务消费者的实现
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/ribbon-consumer.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/ribbon-consumer.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 4.1 基本依赖
 | 
			
		||||
@@ -252,22 +252,22 @@ public class ProductService implements IProductService {
 | 
			
		||||
 | 
			
		||||
启动一个Eureka服务、三个生产者服务(注意区分端口)、和一个消费者服务:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-ribbon-app.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-ribbon-app.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**服务注册中心:**
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-ribbon-eureka.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-ribbon-eureka.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 5.2  验证负载均衡
 | 
			
		||||
 | 
			
		||||
访问 http://localhost:8080/sell/products 查看负载均衡的调用结果:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-ribbon-products-8020.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-ribbon-products-8020.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-ribbon-products-8030.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-ribbon-products-8030.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 六、RestTemplate
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@
 | 
			
		||||
+ **eureka**:注册中心;
 | 
			
		||||
+ **zuul**: API 网关。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-sleuth-zipkin.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-sleuth-zipkin.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 三、Zipkin 服务端
 | 
			
		||||
@@ -43,7 +43,7 @@ java -jar zipkin.jar
 | 
			
		||||
docker run -d -p 9411:9411 openzipkin/zipkin
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zipkin-download.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zipkin-download.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -86,12 +86,12 @@ spring:
 | 
			
		||||
 | 
			
		||||
分别启动 eureka,zuul,consumer,producer 四个项目,访问 http://localhost:9411/ ,查看我们的服务调用链路:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zipkin.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zipkin.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
点击链路,即可以查看具体的调用情况:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zipkin-detail.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zipkin-detail.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
展示信息说明:
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@
 | 
			
		||||
 | 
			
		||||
API 网关是整个微服务系统的门面,所有的外部访问需要通过网关进行调度和过滤。它实现了请求转发、负载均衡、校验过滤、错误熔断、服务聚合等功能:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/apiGateway.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/apiGateway.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 Spring Cloud Zuul
 | 
			
		||||
@@ -46,12 +46,12 @@ Spring Cloud 基于 Net Flix Zuul 实现了网关组件,这就是 Spring Cloud
 | 
			
		||||
 | 
			
		||||
聚合项目目录如下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-cloud-zuul.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-cloud-zuul.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Zuul 项目目录如下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zuul.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zuul.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -181,7 +181,7 @@ zuul:
 | 
			
		||||
 | 
			
		||||
启动 eureka、producer、consumer、zuul 四个服务,访问 localhost:8090/consumer/sell/product :
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zuul-consumer.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zuul-consumer.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -191,7 +191,7 @@ zuul:
 | 
			
		||||
 | 
			
		||||
Zuul 默认整合了 Hystrix ,不用导入其他额外依赖:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zuul-hystrix.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zuul-hystrix.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 4.2 服务降级
 | 
			
		||||
@@ -271,7 +271,7 @@ public class CustomZuulFallbackProvider implements FallbackProvider {
 | 
			
		||||
 | 
			
		||||
正确返回了内容、同时返回的 Http 状态码也和我们设置的一样。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zuul-broker.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zuul-broker.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -361,23 +361,23 @@ public class CustomZuulFilter extends ZuulFilter {
 | 
			
		||||
 | 
			
		||||
Zuul 默认集成了 Ribbon 并实现了负载均衡,只要启动多个实例即可查看到负载均衡的效果:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zuul-ribbon.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zuul-ribbon.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**这里我们直接在idea 中启动多个实例来测试:**
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zuul-config.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zuul-config.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**负载均衡测试结果:**
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zuul-consumer.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zuul-consumer.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zuul-consumer-8040.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zuul-consumer-8040.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/zuul-consumer-8030.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/zuul-consumer-8030.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
2. 自定义切面位于 advice 包下,其中 `CustomAdvice` 是标准的自定义切面,`FirstAdvice` 和 `SecondAdvice` 用于测试多切面共同作用于同一个切入点时的执行顺序;
 | 
			
		||||
3. `OrderService` 是待切入方法。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-aop-annotation.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-aop-annotation.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 依赖说明
 | 
			
		||||
@@ -171,7 +171,7 @@ public class AopTest {
 | 
			
		||||
 | 
			
		||||
- 优先级高的切面在切入方法前执行的通知 ( 如 before) 会优先执行,但是位于方法后执行的通知 ( 如 after,afterReturning ) 反而会延后执行,类似于同心圆原理:
 | 
			
		||||
 | 
			
		||||
  <div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/aop执行顺序.png"/> </div>
 | 
			
		||||
  <div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/aop执行顺序.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
 | 
			
		||||
切面配置位于 resources 下的 `aop.xml` ,其中 CustomAdvice 是自定义切面类,OrderService 是待切入的方法。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-aop.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-aop.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 依赖说明
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
 | 
			
		||||
### 项目目录结构
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-druid-mybatis-annotation.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-druid-mybatis-annotation.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1. 导入依赖
 | 
			
		||||
@@ -82,7 +82,7 @@ public class DispatcherServletInitializer extends AbstractAnnotationConfigDispat
 | 
			
		||||
 | 
			
		||||
### 3. 配置 Druid 监控
 | 
			
		||||
 | 
			
		||||
基于 servlet 3.0 的支持,可以采用注解的方式注册 druid 的 servlet 和 filter。关于 servlet 更多注解支持可以查看 [Servlet 规范文档](https://github.com/heibaiying/spring-samples-for-all/blob/master/referenced%20documents/Servlet3.1%E8%A7%84%E8%8C%83%EF%BC%88%E6%9C%80%E7%BB%88%E7%89%88%EF%BC%89.pdf) 中的 **8.1 小节 注解和可插拔性**
 | 
			
		||||
基于 servlet 3.0 的支持,可以采用注解的方式注册 druid 的 servlet 和 filter。关于 servlet 更多注解支持可以查看 [Servlet 规范文档](https://gitee.com/heibaiying/spring-samples-for-all/raw/master/referenced%20documents/Servlet3.1%E8%A7%84%E8%8C%83%EF%BC%88%E6%9C%80%E7%BB%88%E7%89%88%EF%BC%89.pdf) 中的 **8.1 小节 注解和可插拔性**
 | 
			
		||||
 | 
			
		||||
```java
 | 
			
		||||
@WebServlet(urlPatterns = "/druid/*",
 | 
			
		||||
@@ -353,6 +353,6 @@ public class OracleController {
 | 
			
		||||
 | 
			
		||||
Druid Web 页面访问地址为:http://localhost:8080/druid/index.html ,可以登录后查看数据库相关监控数据:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
 | 
			
		||||
### 项目目录结构
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-druid-mybatis.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-druid-mybatis.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1. 导入依赖
 | 
			
		||||
@@ -363,4 +363,4 @@ public class OracleController {
 | 
			
		||||
 | 
			
		||||
Druid Web 页面访问地址为:http://localhost:8080/druid/index.html ,可以登录后查看数据库相关监控数据:
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||

 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
 | 
			
		||||
另外,本项目 Dubbo 的搭建采用 ZooKeeper 作为注册中心。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-dubbo.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-dubbo.png"/> </div>
 | 
			
		||||
 | 
			
		||||
## 二、项目依赖
 | 
			
		||||
 | 
			
		||||
@@ -61,10 +61,10 @@
 | 
			
		||||
- api 下为公共的调用接口;
 | 
			
		||||
- bean 下为公共的实体类。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/dubbo-ano-common.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/dubbo-ano-common.png"/> </div>
 | 
			
		||||
## 四、 服务提供者
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/dubbo-ano-provider.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/dubbo-ano-provider.png"/> </div>
 | 
			
		||||
### 4.1 提供者配置
 | 
			
		||||
 | 
			
		||||
```java
 | 
			
		||||
@@ -142,7 +142,7 @@ public class ProductService implements IProductService {
 | 
			
		||||
 | 
			
		||||
## 五、服务消费者
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/dubbo-ano-consumer.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/dubbo-ano-consumer.png"/> </div>
 | 
			
		||||
### 5.1 消费者配置
 | 
			
		||||
 | 
			
		||||
```java
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
 | 
			
		||||
另外,本项目 Dubbo 的搭建采用 ZooKeeper 作为注册中心。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-dubbo.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-dubbo.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## 二、项目依赖
 | 
			
		||||
@@ -62,10 +62,10 @@
 | 
			
		||||
- api 下为公共的调用接口;
 | 
			
		||||
- bean 下为公共的实体类。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/dubbo-common.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/dubbo-common.png"/> </div>
 | 
			
		||||
## 四、 服务提供者
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/dubbo-provider.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/dubbo-provider.png"/> </div>
 | 
			
		||||
### 4.1  开发服务
 | 
			
		||||
 | 
			
		||||
productService 是服务的提供者,其实现的接口 IProductService 来源于公共模块,这里商品数据用模拟数据展示:
 | 
			
		||||
@@ -131,7 +131,7 @@ public class ProductService implements IProductService {
 | 
			
		||||
 | 
			
		||||
## 五、服务消费者
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/dubbo-consumer.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/dubbo-consumer.png"/> </div>
 | 
			
		||||
### 5.1 调用服务
 | 
			
		||||
 | 
			
		||||
在 `dubbo.xml` 中调用远程的服务:
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-email-annotation.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-email-annotation.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-email.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-email.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
1. 数据源配置位于 config 目录下的 DatabaseConfig 和 DataSourceConfig;
 | 
			
		||||
2. 项目以单元测试的方法进行测试。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-jdbc-annotation.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-jdbc-annotation.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2  项目依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
 | 
			
		||||
### 1.1  项目结构
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-jdbc.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-jdbc.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2  项目依赖
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ XMemcached 是基于 Java NIO 实现的 Memcached 的高性能客户端,支持
 | 
			
		||||
 | 
			
		||||
Memcached 的整合配置位于 com.heibaiying.config 文件夹下:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-memcached-annotation.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-memcached-annotation.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.3 相关依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ XMemcached 是基于 Java NIO 实现的 Memcached 的高性能客户端,支持
 | 
			
		||||
- Memcached 的整合配置位于 resources 下的 memcached 文件夹下,其中集群配置以 cluster 开头。所有配置按需在 `springApplication.xml` 中用 import 标签导入。
 | 
			
		||||
- 实体类 Programmer 用于测试 Memcached 的序列化与反序列化。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-memcached.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-memcached.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**springapplication.xml 文件:**
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
 | 
			
		||||
配置文件位于 com.heibaiying.config 包下,项目以单元测试的方式进行测试。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-mongodb-annotation.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-mongodb-annotation.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 相关依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
 | 
			
		||||
配置文件位于 resources 下,项目以单元测试的方式进行测试。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-mongodb.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-mongodb.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 相关依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
 | 
			
		||||
### 1.1 项目结构
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-mybatis-annotation.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-mybatis-annotation.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2 项目依赖
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
 | 
			
		||||
### 1.1 项目结构
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-mybatis.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-mybatis.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 项目依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-rabbitmq-annotation.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-rabbitmq-annotation.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-rabbitmq.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-rabbitmq.png"/> </div>
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,7 @@
 | 
			
		||||
 | 
			
		||||
 Redis 所有语言官方推荐的客户端可以在 [客户端](http://www.redis.cn/clients.html) 该网页查看,其中官方推荐的客户端使用了:star:进行标注:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/redis官方推荐客户端.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/redis官方推荐客户端.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 可视化软件 
 | 
			
		||||
@@ -44,7 +44,7 @@
 | 
			
		||||
 | 
			
		||||
+ 实体类 Programmer.java 用于测试 Redisson 序列化与反序列化。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-redis-annotation.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-redis-annotation.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.4 基本依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@
 | 
			
		||||
 | 
			
		||||
 Redis 所有语言官方推荐的客户端可以在 [客户端](http://www.redis.cn/clients.html) 该网页查看,其中官方推荐的客户端使用了:star:进行标注:
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/redis官方推荐客户端.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/redis官方推荐客户端.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 可视化软件 
 | 
			
		||||
@@ -43,7 +43,7 @@
 | 
			
		||||
 | 
			
		||||
+ 实体类 Programmer 用于测试 Redisson 序列化与反序列化。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-redis.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-redis.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
**springapplication.xml 文件:**
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
 | 
			
		||||
关于任务的调度配置定义在 ServletConfig 中,为方便观察定时执行的情况,项目以 web 的方式构建。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-scheduling-annotation.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-scheduling-annotation.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
 | 
			
		||||
关于任务的调度配置定义在 `springApplication.xml` 中,为方便观察定时执行的情况,项目以 web 的方式构建。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-scheduling.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-scheduling.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@
 | 
			
		||||
- webSocketConfig 是 websocket 的主要配置类;
 | 
			
		||||
- 项目以 web 的方式构建。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-websocket-annotation.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-websocket-annotation.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
3. CustomHandershakerInterceptor 为自定义的 websocket 的握手拦截器;
 | 
			
		||||
4. 项目以 web 的方式构建。
 | 
			
		||||
 | 
			
		||||
<div align="center"> <img src="https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/spring-websocket.png"/> </div>
 | 
			
		||||
<div align="center"> <img src="https://gitee.com/heibaiying/spring-samples-for-all/raw/master/pictures/spring-websocket.png"/> </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 1.2 基本依赖
 | 
			
		||||
 
 | 
			
		||||
@@ -1,71 +0,0 @@
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author : heibaiying
 | 
			
		||||
 * @description : 转换本地图片为Github图片工具类
 | 
			
		||||
 */
 | 
			
		||||
public class ChangeImageUrl {
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) throws Exception {
 | 
			
		||||
 | 
			
		||||
        if (args.length < 1) {
 | 
			
		||||
            System.out.println("请传递路径");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String dir = args[0];
 | 
			
		||||
 | 
			
		||||
        String preUrl = "https://github.com/heibaiying/spring-samples-for-all/blob/master/pictures/";
 | 
			
		||||
        String regex = "(!\\[(\\S*)]\\(D:\\\\spring-samples-for-all\\\\pictures\\\\(\\S*)\\)[^(</br>)]*?)";
 | 
			
		||||
 | 
			
		||||
        List<String> filesList = getAllFile(dir, new ArrayList<>());
 | 
			
		||||
        for (String filePath : filesList) {
 | 
			
		||||
            changeImageUrl(filePath, preUrl, regex);
 | 
			
		||||
        }
 | 
			
		||||
        System.out.println("图片地址转换成功!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private static void changeImageUrl(String filePath, String preUrl, String oldImageUrlRegex) throws IOException {
 | 
			
		||||
 | 
			
		||||
        FileReader reader = new FileReader(filePath);
 | 
			
		||||
        StringBuilder stringBuilder = new StringBuilder();
 | 
			
		||||
        char[] chars = new char[1024 * 1024];
 | 
			
		||||
        int read = 0;
 | 
			
		||||
        while ((read = reader.read(chars)) != -1) {
 | 
			
		||||
            stringBuilder.append(new String(chars, 0, read));
 | 
			
		||||
        }
 | 
			
		||||
        reader.close();
 | 
			
		||||
        String content = stringBuilder.toString();
 | 
			
		||||
        //github 居中方式 <div align="center"> <img src=""/> </div>
 | 
			
		||||
        String newContent = content.replaceAll(oldImageUrlRegex,
 | 
			
		||||
                String.format("<div align=\"center\"> <img src=\"%s$3\"/> </div>", preUrl));
 | 
			
		||||
        FileWriter fileWriter = new FileWriter(new File(filePath));
 | 
			
		||||
        fileWriter.write(newContent);
 | 
			
		||||
        fileWriter.flush();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static List<String> getAllFile(String dir, List<String> filesList) {
 | 
			
		||||
        File file = new File(dir);
 | 
			
		||||
        //如果是文件 则不遍历
 | 
			
		||||
        if (file.isFile() && file.getName().endsWith(".md")) {
 | 
			
		||||
            filesList.add(file.getAbsolutePath());
 | 
			
		||||
        }
 | 
			
		||||
        //如果是文件夹 则遍历下面的所有文件
 | 
			
		||||
        File[] files = file.listFiles();
 | 
			
		||||
        if (files != null) {
 | 
			
		||||
            for (File f : files) {
 | 
			
		||||
                if (f.isDirectory() && !f.getName().startsWith(".")) {
 | 
			
		||||
                    getAllFile(f.getAbsolutePath(), filesList);
 | 
			
		||||
                } else if (f.getName().endsWith(".md")) {
 | 
			
		||||
                    filesList.add(f.getAbsolutePath());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return filesList;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,140 +0,0 @@
 | 
			
		||||
import javafx.util.Pair;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileReader;
 | 
			
		||||
import java.io.FileWriter;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.regex.Matcher;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @author : heibaiying
 | 
			
		||||
 * @description : 用于生成README.md导航目录的工具类
 | 
			
		||||
 */
 | 
			
		||||
public class GenNavigation {
 | 
			
		||||
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
 | 
			
		||||
        if (args.length < 1) {
 | 
			
		||||
            System.out.println("请传递路径");
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        String dir = args[0];
 | 
			
		||||
 | 
			
		||||
        List<String> filesList = getAllFile(dir, new ArrayList<>());
 | 
			
		||||
        for (String filePath : filesList) {
 | 
			
		||||
            //  获取文件内容
 | 
			
		||||
            String content = getContent(filePath);
 | 
			
		||||
            // 获取全部标题
 | 
			
		||||
            List<Pair<String, String>> allTitle = getAllTitle(content);
 | 
			
		||||
            // 生成导航
 | 
			
		||||
            String nav = genNav(allTitle);
 | 
			
		||||
            // 写出并覆盖原文件
 | 
			
		||||
            write(filePath, content, nav);
 | 
			
		||||
        }
 | 
			
		||||
        System.out.println("生成目录成功!");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void write(String filePath, String content, String nav) {
 | 
			
		||||
        try {
 | 
			
		||||
            String newContent = "";
 | 
			
		||||
            if (content.contains("## 目录") && content.contains("## 正文<br/>")) {
 | 
			
		||||
                // 如果原来有目录则替换
 | 
			
		||||
                newContent = content.replaceAll("(?m)(## 目录[\\s\\S]*## 正文<br/>)", nav);
 | 
			
		||||
            } else {
 | 
			
		||||
                StringBuilder stringBuilder = new StringBuilder(content);
 | 
			
		||||
                // 如果原来没有目录,则title和正文一个标题间写入
 | 
			
		||||
                int index = content.indexOf("## ");
 | 
			
		||||
                stringBuilder.insert(index - 1, nav);
 | 
			
		||||
                newContent = stringBuilder.toString();
 | 
			
		||||
            }
 | 
			
		||||
            // 写出覆盖文件
 | 
			
		||||
            FileWriter fileWriter = new FileWriter(new File(filePath));
 | 
			
		||||
            fileWriter.write(newContent);
 | 
			
		||||
            fileWriter.flush();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static String genNav(List<Pair<String, String>> flagAndTitles) {
 | 
			
		||||
        StringBuilder builder = new StringBuilder();
 | 
			
		||||
        // 目录头
 | 
			
		||||
        builder.append("## 目录<br/>\n");
 | 
			
		||||
        for (Pair<String, String> ft : flagAndTitles) {
 | 
			
		||||
            String flag = ft.getKey();
 | 
			
		||||
            String title = ft.getValue();
 | 
			
		||||
            builder.append(genBlank(flag.length() - 2, 4));
 | 
			
		||||
            // Github有效目录格式: <a href="#21-预备">页面锚点</a>  url中不能出现特殊符号
 | 
			
		||||
            String formatTitle = title.trim().replaceAll("[.()::()|、,,@。]", "").replace(" ", "-");
 | 
			
		||||
            builder.append(String.format("<a href=\"%s\">%s</a><br/>\n", "#" + formatTitle, title));
 | 
			
		||||
        }
 | 
			
		||||
        // 目录尾
 | 
			
		||||
        builder.append("## 正文<br/>\n");
 | 
			
		||||
        return builder.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static String genBlank(int i, int scale) {
 | 
			
		||||
        StringBuilder builder = new StringBuilder();
 | 
			
		||||
        for (int j = 0; j < i; j++) {
 | 
			
		||||
            for (int k = 0; k < scale; k++) {
 | 
			
		||||
                builder.append(" ");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return builder.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static List<Pair<String, String>> getAllTitle(String content) {
 | 
			
		||||
        List<Pair<String, String>> list = new ArrayList<>();
 | 
			
		||||
        Pattern pattern = Pattern.compile("(?m)^(#{2,10})\\s?(.*)");
 | 
			
		||||
        Matcher matcher = pattern.matcher(content);
 | 
			
		||||
        while (matcher.find()) {
 | 
			
		||||
            String group2 = matcher.group(2);
 | 
			
		||||
            if (!group2.contains("目录") && !group2.contains("正文")) {
 | 
			
		||||
                list.add(new Pair<>(matcher.group(1), group2));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return list;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static String getContent(String filePath) {
 | 
			
		||||
        StringBuilder builder = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            FileReader reader = new FileReader(filePath);
 | 
			
		||||
            char[] chars = new char[1024 * 1024];
 | 
			
		||||
 | 
			
		||||
            int read = 0;
 | 
			
		||||
            while ((read = reader.read(chars)) != -1) {
 | 
			
		||||
                builder.append(new String(chars, 0, read));
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
        return builder.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static List<String> getAllFile(String dir, List<String> filesList) {
 | 
			
		||||
        File file = new File(dir);
 | 
			
		||||
        //如果是文件 则不遍历
 | 
			
		||||
        if (file.isFile() && file.getName().endsWith(".md")) {
 | 
			
		||||
            filesList.add(file.getAbsolutePath());
 | 
			
		||||
        }
 | 
			
		||||
        //如果是文件夹 则遍历下面的所有文件
 | 
			
		||||
        File[] files = file.listFiles();
 | 
			
		||||
        if (files != null) {
 | 
			
		||||
            for (File f : files) {
 | 
			
		||||
                if (f.isDirectory() && !f.getName().startsWith(".")) {
 | 
			
		||||
                    getAllFile(f.getAbsolutePath(), filesList);
 | 
			
		||||
                } else if (f.getName().endsWith(".md")) {
 | 
			
		||||
                    filesList.add(f.getAbsolutePath());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return filesList;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user