目录
初次接触Spring-cloud,有很多东西都要从网上查询,遇到问题往往需要查询作者的1、2、3、4篇系列文章才能解决。特此,标记一下学习Spring-cloud中使用Feign接口服务化的过程。
在springMvc中,一般先开发service,后开发serviceImpl,最后开发controller。
而spring-cloud是微服务的解决方案,那么,正常我们都可能把service、serviceImpl、controller三者都将被拆分到不同的工程内。
这时候,可以使用RestTemplate来解决访问service服务的问题。但是,这是一个需要改造业务代码的解决办法。因此,使用Feign来实现接口服务化,再辅助部分工具,就能快速切换SpringMVC(或者dubbo服务)为spring-cloud。
开发工具:eclipse(官网下载,版本挺新的,能够提示spring-boot相关信息)
Demo工程结构:
一、创建spring-cloud父工程
父工程主要为子模块提供jar版本支持,以及spring-cloud支持。
如图,创建一个simple的project,手动填写pom.xml
此父工程,主要给子工程提供spring-cloud支持。因此,它的pom中,设定parent为spring-boot-starter-parent,且在dependencyManagement中,引入spring-cloud-dependencies。pom.xml代码如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sammy</groupId>
<artifactId>spring.cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<!-- 指定parent,内涵jar版本 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>spring.cloud.eureka</module>
<module>spring.cloud.provider</module>
<module>spring.cloud.consumer</module>
<module>spring.cloud.api</module>
</modules>
</project>
二、创建eureka注册中心
eureka注册中心不用多说,类似zookeeper注册中心,是管理服务的东东。与zookeeper注册中心不同的是,eureka是我们自己用代码建起来的,而zookeeper注册中心是运行了一个zookeeper应用。
在spring.cloud父工程上右键-->new-->project-->maven-->maven module,同样是创建一个simple的project。
1、编辑pom.xml,引入需要的包
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sammy</groupId>
<artifactId>spring.cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring.cloud.eureka</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、编写Application启动类
package com.sammy.cloud.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(EurekaApplication.class, args);
}
}
3、配置application.properties
spring.application.name=spring.cloud.eureka
server.port=8888
eureka.instance.hostname=localhost
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
eureka.client.registerWithEureka=false
eureka.client.fetch-registry=false
三、创建api工程
api工程,用来存放公共代码和接口类。依然是在spring.cloud父工程下创建一个简单的工程。
1、编辑pom.xml,引入需要的包
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sammy</groupId>
<artifactId>spring.cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring.cloud.api</artifactId>
<dependencies>
<!-- 服务调用 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
</project>
2、编写接口
package com.sammy.cloud.biz.hello;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(value = "${feign.service.name}")
public interface HelloBiz {
@RequestMapping("/hello")
public String hello();
}
四、创建provider工程-服务提供者
1、编辑pom.xml,引入需要的包
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sammy</groupId>
<artifactId>spring.cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring.cloud.provider</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.sammy</groupId>
<artifactId>spring.cloud.api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、编写Application启动类
package com.sammy.cloud.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class ProviderApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(ProviderApplication.class, args);
}
}
3、配置application.properties
## 用户服务提供方应用信息
spring.application.name = provider
## 服务端口
server.port = 8001
#配置eureka
eureka.client.serviceUrl.defaultZone = http://localhost:8888/eureka/
eureka.instance.hostname = localhost
eureka.instance.prefer-ip-address = true
eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}
#配置Feign
feign.service.name = ${spring.application.name}
4、编写接口实现类
此处需要注意:该类实现HelloBiz,但注解为RestController,即将该实现类作为Rest服务发布了。
package com.sammy.cloud.provider.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RestController;
import com.sammy.cloud.biz.hello.HelloBiz;
@RestController
public class HelloController implements HelloBiz {
// 通过环境变量,获取当前应用的信息
@Autowired
private Environment environment;
@Override
public String hello() {
return environment.getProperty("spring.application.name") + ":"
+ environment.getProperty("server.port", "8001");
}
}
五、创建Consumer工程-服务消费者
依然是在spring.cloud父工程下创建一个简单的工程。
1、编辑pom.xml,引入需要的包
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.sammy</groupId>
<artifactId>spring.cloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring.cloud.consumer</artifactId>
<dependencies>
<!--eureka客户端,服务消费者也要从注册中心获取可用服务列表-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--springboot支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.sammy</groupId>
<artifactId>spring.cloud.api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
2、编写Application启动类
此处特别注意:EnableFeignClients注解中,basePackages指定扫描包,如我们需要扫描biz包为com.sammy.cloud.biz。
package com.sammy.cloud.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.sammy.cloud.biz"})
public class ConsumerApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(ConsumerApplication.class, args);
}
}
3、配置application.properties
spring.application.name = consumer
server.port = 9001
#提供方服务名称
provider.service.name = provider
#配置eureka
eureka.client.serviceUrl.defaultZone = http://localhost:8888/eureka/
eureka.instance.hostname = localhost
eureka.instance.prefer-ip-address = true
eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port}
#配置Feign
feign.service.name = ${provider.service.name}
4、调用Provider工程中的服务
此处特别注意:使用@Autowired注解引入接口,不再使用RestTemplate来辅助接口访问了。
package com.sammy.cloud.consumer.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.sammy.cloud.biz.hello.HelloBiz;
@RestController
public class ConsumerController {
@Autowired
private HelloBiz helloBiz;
@RequestMapping("/")
public String Home() {
return helloBiz.hello();
}
}
至此,一个spring-cloud的服务调用的demo就搭建完毕了。
依次启动:
1、spring.cloud.eureka:EurekaApplication.java
2、spring.cloud.provider:ProviderApplication.java
3、spring.cloud.consumer:ConsumerApplication.java
启动完毕后,访问: