第一个微服务应用

(git上的源码:https://gitee.com/rain7564/spring_microservices_study/tree/master/first-microservice)

使用idea创建一个基于Spring Cloud的微服务应用
  1. 点击File -> New -> Project,然后出现如下弹窗:


    第一个微服务应用_第1张图片
    image.png
  2. 然后点击Next,输入一些必要信息,如下:


    第一个微服务应用_第2张图片
    image.png
  3. 点击Next,如下:


    第一个微服务应用_第3张图片
    image.png

注:如果没得选(1.5.8),可以随便选一个,然后生成项目后,将版本号改成1.5.8.RELEASE即可。

  1. 点击Next,最后输入Project name和Project location即可,如下:


    第一个微服务应用_第4张图片
    image.png
  2. 等从远程下载项目的.zip文件并解压后,idea会自动将jar包导入,第一次创建Spring Boot项目,加载时间可能会比较久,现在可以先喝杯饮料压压惊~~~
  3. 等项目加载完,第一个微服务应用的雏形就完成了,目录结构如下:


    第一个微服务应用_第5张图片
    image.png

    标准的maven项目,我们重点关注以下几个文件:
    ① Application.java:Spring Boot工程的启动类(已被重命名),打开该文件,如下:

//该注解表明该类是项目(微服务)的启动类
@SpringBootApplication
public class Application {
    //运行该方法,会启动整个Spring Boot服务
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

② application.properties: Spring Boot项目的配置文件。该配置文件可以用来配置诸如数据源等的配置信息。该文件是properties文件,不过Spring Boot还支持另一种文件格式——application.yml,该教程所有配置文件都会使用这种文件格式来配置各种配置信息。
以后还会有一个配置文件——bootstrap.yml,后文会详讲。
虽说是配置文件,但当配置文件为空,整个项目也能跑起来。
③ .gitignore: 刚创建的项目并没有该文件,是后来加上去的,若不需要push到git,可以忽略该文件。
④ pom.xml: 写过maven工程的道友肯定对这个文件很熟悉。没错,这个微服务实际上就是一个maven工程,只是该文件中默认加入了Spring Boot的Maven插件(标签)、从spring-boot-starter-parent继承的版本号(标签)和Spring Boot框架的启动依赖(标签)。

  1. 因为我们要创建的是基于Spring Cloud的微服务应用,所以需要对刚刚创建的项目进行改造,让刚刚创建的项目变成一个父项目,并创建一个子项目:
  • 删掉下图选中的文件/文件:


    第一个微服务应用_第6张图片
    image.png
  • 修改pom.xml文件:


    4.0.0

    cn.study.microservice
    first-microservice
    0.0.1-SNAPSHOT
    pom

    first-microservice
    

    
        org.springframework.boot
        spring-boot-starter-parent
        1.5.8.RELEASE
         
    

    
        UTF-8
        UTF-8
        1.8
    

    
        
            
                org.springframework.cloud
                spring-cloud-dependencies
                Dalston.RELEASE
                pom
                import
            
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


  • 创建一个微服务--licenses-service:
    • 右键项目名,依次选择New->Module:


      第一个微服务应用_第7张图片
      image.png
    • 创建license-service微服务,可参考以下步骤(类似步骤1-4):
第一个微服务应用_第8张图片
image.png
第一个微服务应用_第9张图片
image.png
第一个微服务应用_第10张图片
image.png

点击Finish,项目加载完成后,整个工程的目录树如下:

第一个微服务应用_第11张图片
image.png

简单说明图中部分文件/文件夹:
① license-service:刚刚新建的微服务。一个基于Spring Cloud的微服务应用,可以包含多个这样的微服务。
② LicenseServiceApplication:license-service微服务的启动类。
③ 文件夹static、templates:static存放类似.js、.jpg等静态资源,templates存放.html文件等。接下来都不涉及页面的开发,所以这两个文件夹可以删掉。
④ application.properties:配置文件。
⑤ pom.xml:pom文件。打开文件,可以看到跟刚刚创建的父工程first-microservice的pom文件类似,但是标签中的依赖略有不同,多了"spring-boot-starter-web"、"mysql-connector-java",这两个就是刚刚创建时勾选的"Web"、"MySQL"。也就是说需要什么依赖,可以在创建时勾选对应的jar包即可。同样你也可以直接编辑pom文件,比如添加依赖"spring-boot-starter-data-jpa"。不过一般都是直接跳过勾选,需要什么直接编辑pom文件。你可能会问,那pom文件怎么知道引用哪个版本的依赖,答案可以参考 spring boot的maven配置依赖。
从maven结构来看,first-microservice是license-service的父项目,所以可以对license-service项目的pom文件进行修改,去掉标签,修改标签。如下:



    4.0.0

    cn.study.microservice
    license-service
    0.0.1-SNAPSHOT
    jar

    license-service
    

    
        cn.study.microservice
        first-microservice
        0.0.1-SNAPSHOT
    

    
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-data-jpa
        

        
            mysql
            mysql-connector-java
            runtime
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        
    


可以看到引用了父项目first-microservice,license-service的pom文件继承了first-microservice的pom文件。

  • 删除下图选中的文件/文件夹,并重命名启动类和配置文件:
第一个微服务应用_第12张图片
image.png
  • 创建License.java和LicenseController.java:
package cn.study.microservice.license.domain;

public class License{
    private String id;
    private String organizationId;
    private String productName;
    private String licenseType;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getOrganizationId() {
        return organizationId;
    }

    public void setOrganizationId(String organizationId) {
        this.organizationId = organizationId;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getLicenseType() {
        return licenseType;
    }

    public void setLicenseType(String licenseType) {
        this.licenseType = licenseType;
    }

    public License withId(String id){
        this.setId( id );
        return this;
    }

    public License withOrganizationId(String organizationId){
        this.setOrganizationId(organizationId);
        return this;
    }

    public License withProductName(String productName){
        this.setProductName(productName);
        return this;
    }

    public License withLicenseType(String licenseType){
        this.setLicenseType(licenseType);
        return this;
    }
}
/**
 * 该注解相当于@ResponseBody + @Controller合在一起的作用
 * 会将request/response序列化/反序列化为JSON格式
 */
@RestController
@RequestMapping(value="v1/organizations/{organizationId}/licenses")
public class LicenseServiceController {

    @RequestMapping(value="/{licenseId}",method = RequestMethod.GET)
    public License getLicenses( @PathVariable("organizationId") String organizationId,
                                @PathVariable("licenseId") String licenseId) {
        //@PathVariable能将URL中{organizationId}、{licenseId}映射到方法的变量organizationId、licenseId
        return new License()
                .withId(licenseId)
                .withOrganizationId(organizationId)
                .withProductName("Teleco")
                .withLicenseType("Seat");
    }

    @RequestMapping(value="{licenseId}",method = RequestMethod.PUT)
    public String updateLicenses( @PathVariable("licenseId") String licenseId) {
        return String.format("This is the put");
    }

    @RequestMapping(value="{licenseId}",method = RequestMethod.POST)
    public String saveLicenses( @PathVariable("licenseId") String licenseId) {
        return String.format("This is the post");
    }

    @RequestMapping(value="{licenseId}",method = RequestMethod.DELETE)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public String deleteLicenses( @PathVariable("licenseId") String licenseId) {
        return String.format("This is the Delete");
    }

}
  • 启动,以下为idea的几种启动方式:
第一个微服务应用_第13张图片
image.png

启动后,可在控制台看到类似下图的打印效果:


image.png
  • 测试,验证结果
    在浏览器或使用postman进行调试。
    • 浏览器:在地址栏输入:http://localhost:8080/v1/organizations/1001/licenses/100001
      可以看到类似如下图的效果:
      image.png
    • 使用postman调试:效果如下:


      第一个微服务应用_第14张图片
      image.png

至此,第一个基于Spring Cloud的微服务应用搭建完成,这只是一个最简单的微服务应用,还没涉及到Spring Cloud的五大神兽:

  • 服务发现——Netflix Eureka
  • 客服端负载均衡——Netflix Ribbon
  • 断路器——Netflix Hystrix
  • 服务网关——Netflix Zuul
  • 分布式配置——Spring Cloud Config

下一节,将介绍第一个神兽:Netflix Eureka(服务注册与发现)。

你可能感兴趣的:(第一个微服务应用)