起因

事情是这样的,最近在学习spring cloud相关知识,就想把之前做的一个项目拆分成一个微服务项目

我就把用户相关的模块和帖子相关的模块分开了

但是帖子模块是要依赖于用户模块的,于是问题就产生了

现象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Autowired
PostService postService;

@Autowired
UserService userService;

@CrossOrigin
@GetMapping("/api/postList")
public List<Map<String,Object>> postList() {
List<Map<String,Object>> resultList = new ArrayList<>();
List<Post> contentList = postService.findAllContent();

//根据帖子找用户,一个map对应一个帖子和用户,最后返回一个map集合
for(Post content : contentList){
Map<String, Object> map = new HashMap<>();
User user = userService.findUserById(content.getPostUserId());
map.put("user",user);
map.put("content",content);
resultList.add(map);
}
return resultList;
}

我这有个接口,会调用到UserService中的方法,如果我直接到包,然后再自动注入,使用UserService是不行的,会报错Invalid bound statement (not found)

image-20210922202730642

UserService是没有问题的,应为在用户服务调用是可以从数据库查出信息的,帖子服务这样使用不行

解决方法

我的解决方法是,在用户服务提供一个对外的接口

1
2
3
4
@GetMapping("/getUserById/{id}")
public User getUserById(@PathVariable("id") int id){
return userService.findUserById(id);
}

再在帖子服务里面写一个openfeign接口

1
2
3
4
5
@FeignClient(name = "user-service", path = "/user")
public interface UserServiceFeign {
@GetMapping("/getUserById/{id}")
User getUserById(@PathVariable("id") int id);
}

最后将帖子服务修改一下,不使用UserService,使用openfeign调用用户服务的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Autowired
PostService postService;

@Autowired
UserServiceFeign userServiceFeign;

@CrossOrigin
@GetMapping("/api/postList")
public List<Map<String,Object>> postList() {
List<Map<String,Object>> resultList = new ArrayList<>();
List<Post> contentList = postService.findAllContent();

//根据帖子找用户,一个map对应一个帖子和用户,最后返回一个map集合
for(Post content : contentList){
Map<String, Object> map = new HashMap<>();
User user = userServiceFeign.getUserById(content.getPostUserId());
map.put("user",user);
map.put("content",content);
resultList.add(map);
}
return resultList;
}

image-20210922203352174

这样就ok了。

openfeign具体使用方法

导入依赖

1
2
3
4
5
6
7
8
9
10
<!-- openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 负载均衡loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

除了openfeign的依赖,还要导入loadbalancer的依赖

服务接口

1
2
3
4
5
6
7
8
9
10
11
12
package com.fizzy.postservice.feign;

import com.fizzy.core.entity.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "user-service", path = "/user")
public interface UserServiceFeign {
@GetMapping("/getUserById/{id}")
User getUserById(@PathVariable("id") int id);
}

加上**@FeignClient注解,name就是注册中心服务的名字,path**就是要调用接口的第一个路径

image-20210922203825668

接口里面的方法,就根据服务里面的方法写。

使用

1
2
3
4
@Autowired
UserServiceFeign userServiceFeign;

User user = userServiceFeign.getUserById(content.getPostUserId());

就自动注入在调用就行了,是不是跟mybatis的使用方法有点像

启动类添加注解

1
2
3
4
5
6
@EnableFeignClients
public class PostApplication {
public static void main(String[] args) {
SpringApplication.run(PostApplication.class, args);
}
}

启动类要添加**@EnableFeignClients**注解