二、基于feign的工程化项目创建
2.1、案例目标及项目架构图
api模块依赖domain模块,然后其他服务依赖该api接口模块。
domain:实体类。
api:放置公共接口,例如feign接口。
2.2、实战—项目模块搭建
2.2.1、各个模块介绍及父模块pom.xml
项目模块展示:
注册中心:使用之前eureka案例中的即可
接着按照2.1中的项目架构图来进行搭建模块,分别是:api模块、doamin模块、order服务模块以及user服务模块
依赖关系如下:
api模块依赖domain模块。
domain:添加对应的实体类。
api:主要是编写对应的远程调用api接口以及断路器实现类。
order、user服务模块依赖api模块。
order服务主要是对外提供服务。
user服务中某个接口会进行调用order服务。
所有的包名统一前缀为com.changlu。
对于04-feign-project父模块的pom.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?> <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"> <!-- 父模块依赖 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.12.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <modelVersion>4.0.0</modelVersion> <!-- 创建好子模块之后,就会自动添加packaging以及modules管理 --> <groupId>com.changlu</groupId> <artifactId>04-feign-project</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>domain-project</module> <module>common-api</module> <module>user-center</module> <module>order-center</module> </modules> <!--全局版本控制--> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR12</spring-cloud.version> </properties> <!-- 全局依赖的模块 --> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <!-- 全局管理的依赖版本(不会被直接引入) --> <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> <!-- 打包编译 --> <!-- <build>--> <!-- </build>--> </project>
2.2.2、domain-project模块
说明:该模块主要放置一些实体类。
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <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"> <parent> <artifactId>04-feign-project</artifactId> <groupId>com.changlu</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>domain-project</artifactId> </project>
Order.java实体类:
package com.changlu.domain; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; /** * @Description: * @Author: changlu * @Date: 2:30 PM */ @Data @AllArgsConstructor @NoArgsConstructor @Builder public class Order { private Integer orderId; private String orderName; private Double price; }
2.2.3、common-api模块
说明:这个模块主要放一些公共的api接口,例如feign接口以及hystrix断路器接口。
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <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"> <parent> <artifactId>04-feign-project</artifactId> <groupId>com.changlu</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>common-api</artifactId> <dependencies> <!-- 依赖domain --> <dependency> <groupId>com.changlu</groupId> <artifactId>domain-project</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> </dependencies> </project>
com/changlu/feign/UserOrderFeign.java:feign接口规范
package com.changlu.feign; import com.changlu.domain.Order; import com.changlu.feign.hystrix.*; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; /** * @Description: * @Author: changlu * @Date: 2:39 PM */ @FeignClient(value = "order-service", fallback = UserOrderFeignHystrix.class) public interface UserOrderFeign { @GetMapping("/order/{id}") Order getOrderById(@PathVariable("id")Integer id); }
com.changlu.feign.hystrix.UserOrderFeignHystrix:对应上面feign的断路器
package com.changlu.feign.hystrix; import com.changlu.domain.Order; import com.changlu.feign.UserOrderFeign; import org.springframework.stereotype.Component; /** * @Description: * @Author: changlu * @Date: 2:43 PM */ @Component public class UserOrderFeignHystrix implements UserOrderFeign { @Override public Order getOrderById(Integer id) { return null; } }
2.2.4、order-center服务模块
说明:该模块主要是对外提供订单服务。
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <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"> <parent> <artifactId>04-feign-project</artifactId> <groupId>com.changlu</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>order-center</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <!-- 引入api依赖 --> <dependency> <groupId>com.changlu</groupId> <artifactId>common-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> </project>
配置文件application.yaml:
server: port: 8081 spring: application: name: order-service eureka: client: service-url: defaultZone: http://localhost:8761/eureka instance: hostname: localhost instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
①添加启动器注解,开启服务注册
package com.changlu; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; /** * @Description: * @Author: changlu * @Date: 2:36 PM */ @SpringBootApplication @EnableEurekaClient public class OrderServiceApplication { public static void main(String[] args) { SpringApplication.run(OrderServiceApplication.class, args); } }
②创建订单控制器:com.changlu.controller.OrderController
package com.changlu.controller; import com.changlu.domain.Order; import com.changlu.feign.UserOrderFeign; import org.springframework.web.bind.annotation.RestController; /** * @Description: * @Author: changlu * @Date: 2:38 PM */ @RestController public class OrderController implements UserOrderFeign { @Override public Order getOrderById(Integer id) { Order order = Order.builder() .orderId(id) .price(100.0) .orderName("牛奶布丁").build(); return order; } }
2.2.5、user-center服务模块
说明:该用户服务主要是对外提供用户服务,在提供用户服务过程中会进行调用订单服务,其中就涉及到了openfeign组件以及hystrix断路器组件(需要手动开启)。
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <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"> <parent> <artifactId>04-feign-project</artifactId> <groupId>com.changlu</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>user-center</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <!-- 引入api依赖 --> <dependency> <groupId>com.changlu</groupId> <artifactId>common-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> </project>
配置文件application.yaml:
server: port: 8082 spring: application: name: user-service eureka: client: service-url: defaultZone: http://localhost:8761/eureka instance: hostname: localhost instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port} # 开启熔断 feign: hystrix: enabled: true
①创建启动器,添加服务注册以及feign包扫描
package com.changlu; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; import org.springframework.cloud.openfeign.EnableFeignClients; /** * @Description: * @Author: changlu * @Date: 2:52 PM */ @SpringBootApplication @EnableEurekaClient @EnableFeignClients(basePackages = "com.changlu.feign") public class UserServiceApplication { public static void main(String[] args) { SpringApplication.run(UserServiceApplication.class, args); } }
②创建用户控制器:com.changlu.controller.UserController
package com.changlu.controller; import com.changlu.domain.Order; import com.changlu.feign.UserOrderFeign; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; /** * @Description: * @Author: changlu * @Date: 2:53 PM */ @RestController public class UserController { @Autowired private UserOrderFeign feign; @GetMapping("/user/order/{userId}") public Order getOrderByUserId(@PathVariable("userId")Integer userId) { //根据用户id获取到订单id Integer id = 1111; Order order = feign.getOrderById(id); return order; } }
至此,我们的项目模块搭建完成。
2.3、项目模块测试、
我们启动注册中心、订单服务以及用户服务:
接着我们来访问用户服务:http://localhost:8082/user/order/123
接着我们将订单服务关闭,再此访问查看下:
成功,当订单服务不可用时,即可返回对应断路器的内容。