【发布时间】:2019-10-22 18:46:47
【问题描述】:
我正在编写一个 rest api 客户端,它需要连接到不同端点上的一些 API(相同的 API),所有这些都提供相同的数据。为此,我需要动态设置每个调用 url 和 auth 标头。由于我使用 spring 作为框架,我的计划是使用 feign 作为其余客户端。
下面是我需要在代码中做的事情
Feign 客户端:
@FeignClient(
name = "foo",
url = "http://placeholderThatWillNeverBeUsed.io",
fallbackFactory = ArticleFeignClient.ArticleClientFallbackFactory.class
)
public interface ArticleFeignClient {
@GetMapping(value = "articles/{id}", consumes = "application/json", produces = "application/json")
public ArticleResponse getArticles(URI baseUrl, @RequestHeader("Authorization") String token, @PathVariable Integer id);
@GetMapping(value = "articles", consumes = "application/json", produces = "application/json")
public MultiArticleResponse getArticles(URI baseUrl, @RequestHeader("Authorization") String token);
}
手动丰富参数的ArticleClient:
@Service
public class ArticleClient extends AbstractFeignClientSupport {
private final ArticleFeignClient articleFeignClient;
@Autowired
public ArticleClient(ArticleFeignClient articleFeignClient, AccessDataService accessDataService) {
super(accessDataService);
this.articleFeignClient = articleFeignClient;
}
public ArticleResponse getArticles(String connection, Integer id) {
var accessData = getAccessDataByConnection(connection);
return articleFeignClient.getArticles(URI.create(accessData.getEndpoint()), "Basic " + getAuthToken(accessData),id);
}
public MultiArticleResponse getArticles(String connection) {
var accessData = getAccessDataByConnection(connection);
return articleFeignClient.getArticles(URI.create(accessData.getEndpoint()), "Basic " + getAuthToken(accessData));
}
}
拥有丰富器的客户端支持
public abstract class AbstractFeignClientSupport {
private final AccessDataService accessDataService;
public AbstractFeignClientSupport(AccessDataService accessDataService) {
this.accessDataService = accessDataService;
}
final public AccessData getAccessDataByConnection(@NotNull String connection) {
return accessDataService.findOneByConnection(connection).orElseThrow();
}
}
如你所见,会有很多重复
var accessData = getAccessDataByConnection(connection);
return clientToCall.methodToCall(URI.create(accessData.getEndpoint()), "Basic " + getAuthToken(accessData),id);
这只是将请求的 URI 和 Auth Header 添加到实际 feign 客户端的方法调用中。
我想知道是否有更好的方法,并且一直在研究使用 AOP 或注释来拦截我的方法调用,为给定包(或带注释的方法)中的每个调用添加两个参数,这样我就可以只需担心一次,无需重复 40 种左右的方法。
有吗?如果有,怎么做?
【问题讨论】:
-
是的,AOP 可以工作;创建一个调整方法参数的“Around”建议。我会说这里有点太复杂了,无法正确介绍这里需要什么。您需要首先决定建议哪些方法以及如何确定它们(带有注释的 eq 标记),然后创建一个实现您想要的逻辑的建议。