gpt4 book ai didi

java - 拦截方法调用并添加/丰富参数

转载 作者:行者123 更新时间:2023-12-02 01:28:27 25 4
gpt4 key购买 nike

我正在编写一个rest api客户端,它需要连接到不同端点上的一些API(相同的API),所有端点都提供相同的数据。为此,我需要动态设置每个调用 url 和 auth header 。由于我使用 spring 作为框架,所以我的计划是使用 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 种左右的方法。

有吗?如果是这样,怎么办?

最佳答案

从类型安全角度来看,方面往往是一件相当肮脏的事情。

例如,要操作传递给方法的 List,您首先需要从连接点提供的元信息中提取它。这看起来有点像这样:

@Pointcut("within(@com.your.company.SomeAnnotationType *)")
public void methodsYouWantToAdvise() {};

@Aspect
public class AddToList {
@Around("methodsYouWantToAdvise()")
public Object addToList(ProceedingJoinPoint thisJoinPoint) throws Throwable {
Object[] args = thisJoinPoint.getArgs();
// you know the first parameter is the list you want to adjust
List l = (List) args[0];
l.add("new Value");

thisJoinPoint.proceed(args);
}

这肯定可以做得更好,但这几乎是如何实现这样一个方面的要点。

也许check out this article至少让基础运转起来。

关于java - 拦截方法调用并添加/丰富参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56491294/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com