首先,三板斧:
- 依赖
org.springframework.cloud spring-cloud-starter-openfeign
- 配置: 无
- 注释: 无
启动类中代码如下:
@SpringBootApplication
@MapperScan("com.zstu")
@EnableFeignClients
public class ContentCenterApplication {
public static void main(String[] args) {
SpringApplication.run(ContentCenterApplication.class, args);
}
//在spring容器中,创建一个对象,类型RestTemplate,名称是restTemplate()
//
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
下面是更改的代码:
public class ShareService {
private final ShareMapper shareMapper;
private final UserCenterFeignClient userCenterFeignClient;
public ShareDTO findById(Integer id) {
Share share = this.shareMapper.selectByPrimaryKey(id);
//获取发布人的id
Integer userId = share.getUserId();
UserDTO userDTO = this.userCenterFeignClient.findById(userId);
//拿到用户中心的所有实例信息
//怎么调用用户微服务的/users/{userId}?
//消息的装配
ShareDTO shareDTO = new ShareDTO();
BeanUtils.copyProperties(share, shareDTO);
shareDTO.setWxNickname(userDTO.getWxNickname());
return shareDTO;
}
package com.zstu.contentcenter.feignclient;
import com.zstu.contentcenter.domain.dto.user.UserDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name = "user-center")
public interface UserCenterFeignClient {
@GetMapping("/users/{id}")
UserDTO findById(@PathVariable Integer id);
}
feign打印日志:
logging:
level:
com.zstu: debug
- java代码实现配置日志
logging:
level:
com.zstu.contentcenter.feignclient.UserCenterFeignClient: debug
package com.zstu.contentcenter.feignclient;
import com.zstu.contentcenter.configuration.UserCenterFeignConfiguration;
import com.zstu.contentcenter.domain.dto.user.UserDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(name = "user-center", configuration = UserCenterFeignConfiguration.class)
public interface UserCenterFeignClient {
@GetMapping("/users/{id}")
UserDTO findById(@PathVariable Integer id);
}
package com.zstu.contentcenter.configuration;
import feign.Logger;
import org.springframework.context.annotation.Bean;
public class UserCenterFeignConfiguration {
@Bean
public Logger.Level level() {
//让feign打印所有请求的细节
return Logger.Level.FULL;
}
}
我们测试一下,发现打印日志了
- 这里我们需要有一个注意点
package com.zstu.contentcenter.configuration;
import feign.Logger;
import org.springframework.context.annotation.Bean;
@configuration
public class UserCenterFeignConfiguration {
@Bean
public Logger.Level level() {
//让feign打印所有请求的细节
return Logger.Level.FULL;
}
}
这里加上了configuration后,会造成父子上下文的重复扫描,去除或者移动文件到启动类扫描不到的文件下
- 使用配置实现相同的日志效果
feign:
client:
config:
#想要调用的微服务的名称
user-center:
loggerLevel: full
package com.zstu.contentcenter.feignclient;
import com.zstu.contentcenter.configuration.UserCenterFeignConfiguration;
import com.zstu.contentcenter.domain.dto.user.UserDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
//@FeignClient(name = "user-center", configuration = UserCenterFeignConfiguration.class)
@FeignClient(name = "user-center")
public interface UserCenterFeignClient {
@GetMapping("/users/{id}")
UserDTO findById(@PathVariable Integer id);
}
我们测试一下,发现也一样打印日志
- feign的全局配置
代码配置
@EnableFeignClients(defaultConfiguration = GlobalFeignConfiguration.class)
属性配置
feign:
client:
config:
#全局配置
default:
loggerLevel: full
package com.zstu.contentcenter;
import com.zstu.contentcenter.configuration.GlobalFeignConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@MapperScan("com.zstu")
@EnableFeignClients//(defaultConfiguration = GlobalFeignConfiguration.class)
public class ContentCenterApplication {
public static void main(String[] args) {
SpringApplication.run(ContentCenterApplication.class, args);
}
//在spring容器中,创建一个对象,类型RestTemplate,名称是restTemplate()
//
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
属性配置总结
> Ribbon 和 Feign的比较
优先级:
全局代码<全局属性<细粒度代码<细粒度属性
尽量使用一种属性配置
- 多参数请求构造:
方法1
@GetMapping("/q")
public User query(User user) {
return user;
}
@Autowired
private TestUserCenterFeignClient testUserCenterFeignClient;
@GetMapping("/test-get")
public UserDTO query(UserDTO userDTO) {
return testUserCenterFeignClient.query(userDTO);
}
package com.zstu.contentcenter.feignclient;
import com.zstu.contentcenter.domain.dto.user.UserDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "user-center")
public interface TestUserCenterFeignClient {
@GetMapping("/q")
UserDTO query(UserDTO userDTO);
}
main:
allow-bean-definition-overriding: true
#
这里我们需要注意点额一点是,为什么需要加上这么一段配置?
因为下图,两个接口中,我都使用了@FeignClient(name = "user-center"),使用了两个接口,而且同名了,出了问题
@Autowired
private TestUserCenterFeignClient testUserCenterFeignClient;
@GetMapping("/test-get")
public UserDTO query(UserDTO userDTO) {
return testUserCenterFeignClient.query(userDTO);
}
@FeignClient(name = "user-center")
public interface TestUserCenterFeignClient {
@GetMapping("/q")
UserDTO query(@SpringQueryMap UserDTO userDTO);
}
这里参考学习大目老师视频中的手记http://www.imooc.com/article/289000
- 方法2
@FeignClient(name = "microservice-provider-user")
public interface UserFeignClient {
@RequestMapping(value = "/get", method = RequestMethod.GET)
public User get1(@RequestParam("id") Long id, @RequestParam("username") String username);
}
- Feign脱离Ribbon使用方式
@Autowired
private TestBaiduFeignClient testBaiduFeignClient;
@GetMapping("/baidu")
public String baiduIndex() {
return this.testBaiduFeignClient.index();
}
package com.zstu.contentcenter.feignclient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
//注意,这里分name = xxx,不可以省略,但是可以自定义,不然不可以启动
@FeignClient(name = "baidu", url = "http://www.baidu.com")
public interface TestBaiduFeignClient {
@GetMapping("")
String index();
}
- feign连接池
三板斧:
依赖:
io.github.openfeign feign-httpclient
配置
feign:
client:
config:
#全局配置
default:
loggerLevel: full
httpclient:
enabled: true
#feign的最大连接数
max-connections: 200
#feign单个路劲的最大连接数
max-connections-per-route: 50
#让feign使用Apache httpclient做请求,而不是默认的urlconnection
#feign底层不仅支持URL connection 还支持Apache httpclient ,还支持okhttp
okhttp: enabled: true #如果使用okhttp,则需要将别的enable删除 io.github.openfeign >feign-okhttp10.1.0
feign常见问题:http://www.imooc.com/article/289005
keep moving~~



