二、REST風格微服務架構搭建
使用SpringBoot、SpringCloud、Mybatis建立一個簡單CURD的Rest風格微服務架構。
專案程式碼結構:
1、父工程建立
首先建立一個父專案microservice
,用來統一管理專案依賴版本,注意建立的是maven pom專案。
pom.xml
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source >
<maven.compiler.target>1.8</maven.compiler.target>
<druid.version>1.1.6</druid.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- SpringCloud,注意匯入型別為pom -->
<dependency>
<groupId >org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency >
<!-- SpringBoot,注意匯入型別為pom -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.13.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring-Mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!-- 連線池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
2、公共模組建立,主要存放實體類,工具類等一些共用的東西。
建立maven module專案microservice-common
,預設的jar型別
pom.xml
<dependencies>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
建立實體類:Dept.java
@Data //使用Lombok簡化工作
//@Accessors(chain=true) //可以使用鏈式風格
public class Dept implements Serializable {
private Integer deptId;
private String deptName;
}
建立完成後,maven clean install
生成jar到本地倉庫,方便其他專案引用。
3、服務提供模組建立
建立maven module專案 microservice-dept-provider-8001
,以後可能有多個服務,帶上埠號,便於區分
pom.xml
<dependencies>
<!-- 引入公共模組 -->
<dependency>
<groupId>org.pu</groupId>
<artifactId>microservice-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
</dependencies>
配置application.yml
server:
context-path: /
port: 8001 #配置埠
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_springcloud?useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
#mybatis配置
mybatis:
config-location: classpath:mybatis/mybatis-config.xml # mybatis配置檔案
type-aliases-package: org.pu.dept.entity # entity別名所在類
mapper-locations:
- classpath:mybatis/mapper/**/*.xml # mapper對映檔案
編寫dao層操作DeptMapper.java
/**
* 資料庫操作
* 注意新增mybatis @Mapper註解
* @author dave
*
*/
@Mapper
public interface DeptMapper {
@Select("select * from t_dept")
@Results({ @Result(id = true, column = "dept_id", property = "deptId"),
@Result(column = "dept_name", property = "deptName") })
public List<Dept> selectList();
@Select("select * from t_dept where dept_id = #{id}")
public Dept selectById(Integer id);
@Update("update t_dept t set t.dept_name = #{deptName} where dept_id = #{deptId}")
public int update(Dept dept);
@Options(useGeneratedKeys = true, keyProperty = "deptId")
@Insert("insert into t_dept (dept_name) values (#{deptName})")
public int insert(Dept dept);
@Delete("delete from t_dept where dept_id = #{id}")
public int deleteById(Integer id);
}
編寫Service介面DeptService
和它的實現類DeptServiceImpl
public interface DeptService {
//查詢所有
public List<Dept> selectList();
//通過ID查詢
public Dept selectById(Integer id);
//更新
public int update(Dept dept);
//插入
public int insert(Dept dept);
//刪除
public int deleteById(Integer id);
}
@Service("deptService")
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
public List<Dept> selectList() {
return deptMapper.selectList();
}
//......
}
編寫Controller層DeptController.java
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@GetMapping("/depts")
public List<Dept> depts() {
return deptService.selectList();
}
@GetMapping("/dept/{id}")
public Dept dept(@PathVariable(value = "id") Integer id) {
return deptService.selectById(id);
}
@PostMapping("/dept")
public Dept insert(@RequestBody Dept dept) {
deptService.insert(dept);
return dept;
}
@PutMapping("/dept")
public Dept update(@RequestBody Dept dept) {
deptService.update(dept);
return dept;
}
@DeleteMapping("/dept/{id}")
public boolean delete(@PathVariable(value = "id") Integer id) {
return deptService.deleteById(id) > 0;
}
}
啟動專案後,使用Postman進行測試:
4、消費端模組建立
建立maven module專案 microservice-dept-consumer-80
,帶上埠號,便於區分
pom.xml
<dependencies>
<!-- 引入公共模組 -->
<dependency>
<groupId>org.pu</groupId>
<artifactId>microservice-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- SpringBoot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
配置application.yml
server:
context-path: /
port: 80
傳統情況下在java程式碼裡訪問restful服務,一般使用Apache
的HttpClient
。不過此種方法使用起來太過繁瑣。spring提供了一種簡單便捷的模板類來進行操作,這就是RestTemplate
。 springcloud消費者,服務提供者之間的互動是HTTP REST方式 ,比dubbo RPC方式更加靈活方便點;
具體可參考官方API文件:
編寫配置類RestTemplateConfig
,將RestTemplate加入容器:
@Configuration
public class RestTemplateConfig {
/**
* 呼叫restful服務模版,客戶端模版工具
* @return
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
編寫Controller層DeptConsumerController
:
@RequestMapping("/consumer")
@RestController
public class DeptConsumerController {
private final static String URL_PREFIX = "http://localhost:8001";
@Autowired
private RestTemplate restTemplate;
@SuppressWarnings("unchecked")
@GetMapping("/depts")
public List<Dept> depts() {
return restTemplate.getForObject(URL_PREFIX + "/depts", List.class);
}
@GetMapping("/dept/{id}")
public Dept dept(@PathVariable(value = "id") Integer id) {
return restTemplate
.getForObject(URL_PREFIX + "/dept/" + id, Dept.class);
}
@PostMapping("/dept")
public Dept insert(@RequestBody Dept dept) {
return restTemplate.postForObject(URL_PREFIX + "/dept", dept,
Dept.class);
}
@PutMapping("/dept")
public Dept update(@RequestBody Dept dept) {
restTemplate.put(URL_PREFIX + "/dept", dept, Dept.class);
return dept;
}
@DeleteMapping("/dept/{id}")
public boolean delete(@PathVariable(value = "id") Integer id) {
try {
restTemplate.delete(URL_PREFIX + "/dept/" + id);
return true;
} catch (Exception e) {
return false;
}
}
}
啟動消費者應用,使用Postman測試: