1. 程式人生 > >二、REST風格微服務架構搭建

二、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服務,一般使用ApacheHttpClient。不過此種方法使用起來太過繁瑣。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測試:

這裡寫圖片描述