如何通过application.properties配置Spring @HttpExchange接口以对接不同外部服务
如何通过application.properties配置Spring @HttpExchange接口以对接不同外部服务
嘿,这个需求我刚好实操过,完全可以借助Spring的配置体系优雅搞定~ 结合你的场景(两个API相似但互不相关的外部服务),给你一步步拆解实现方案:
1. 定义通用的@HttpExchange接口
因为两个服务API逻辑相似,我们先抽一个通用接口,不要把基础URL写死在注解里,留到配置中注入:
public interface PriceServiceApi { @HttpExchange("/api/v1/price") ResponseEntity<PriceResponse> getCurrentPrice(); }
(这里的PriceResponse是你自定义的响应实体类,根据服务返回结构调整即可)
2. 在application.properties中配置两个服务的参数
把两个服务的基础地址、超时时间这些可变配置放到配置文件里,方便后续修改:
# 黄金价格服务配置 gold-service.base-url=http://some-gold-price-service.com gold-service.connect-timeout=5000 gold-service.read-timeout=10000 # 白银价格服务配置 silver-service.base-url=http://some-silver-price-service.com silver-service.connect-timeout=5000 silver-service.read-timeout=10000
3. 编写配置类绑定配置并生成代理实例
用@ConfigurationProperties来优雅绑定配置文件中的参数,再分别为两个服务创建对应的HttpServiceProxyFactory和代理接口实例:
先写配置属性类
@ConfigurationProperties(prefix = "gold-service") @Data // 用Lombok简化getter/setter,没有的话自己写也可以 public class GoldServiceProperties { private String baseUrl; private int connectTimeout; private int readTimeout; } @ConfigurationProperties(prefix = "silver-service") @Data public class SilverServiceProperties { private String baseUrl; private int connectTimeout; private int readTimeout; }
再写核心配置类
@Configuration @EnableConfigurationProperties({GoldServiceProperties.class, SilverServiceProperties.class}) public class ExternalServiceConfig { // 生成黄金服务的代理实例 @Bean("goldPriceService") public PriceServiceApi goldPriceService(GoldServiceProperties properties) { // 配置HTTP客户端参数 HttpClient httpClient = HttpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, properties.getConnectTimeout()) .responseTimeout(Duration.ofMillis(properties.getReadTimeout())); ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient); // 构建代理工厂并生成接口实例 HttpServiceProxyFactory factory = HttpServiceProxyFactory .builder(ClientHttpConnectorAdapter.forConnector(connector)) .baseUrl(properties.getBaseUrl()) .build(); return factory.createClient(PriceServiceApi.class); } // 生成白银服务的代理实例 @Bean("silverPriceService") public PriceServiceApi silverPriceService(SilverServiceProperties properties) { HttpClient httpClient = HttpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, properties.getConnectTimeout()) .responseTimeout(Duration.ofMillis(properties.getReadTimeout())); ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient); HttpServiceProxyFactory factory = HttpServiceProxyFactory .builder(ClientHttpConnectorAdapter.forConnector(connector)) .baseUrl(properties.getBaseUrl()) .build(); return factory.createClient(PriceServiceApi.class); } }
注:如果你的项目用的是同步HTTP客户端,把
ReactorClientHttpConnector换成SimpleClientHttpRequestFactory即可,适配方式类似。
4. 业务代码中区分使用两个代理实例
通过@Qualifier注解指定要注入的具体实例,就能分别调用两个外部服务了:
@Service public class PriceFetchService { private final PriceServiceApi goldPriceService; private final PriceServiceApi silverPriceService; // 构造注入时用@Qualifier指定bean名称 public PriceFetchService(@Qualifier("goldPriceService") PriceServiceApi goldPriceService, @Qualifier("silverPriceService") PriceServiceApi silverPriceService) { this.goldPriceService = goldPriceService; this.silverPriceService = silverPriceService; } public void fetchAndProcessPrices() { ResponseEntity<PriceResponse> goldPriceResp = goldPriceService.getCurrentPrice(); ResponseEntity<PriceResponse> silverPriceResp = silverPriceService.getCurrentPrice(); // 这里处理两个服务返回的价格数据 System.out.println("当前黄金价格:" + goldPriceResp.getBody().getPrice()); System.out.println("当前白银价格:" + silverPriceResp.getBody().getPrice()); } }
额外小提示
如果两个服务的API有细微差异(比如某个接口路径不同),可以让特定接口继承通用接口,用@HttpExchange覆盖路径:
public interface SilverPriceServiceApi extends PriceServiceApi { @Override @HttpExchange("/api/v2/silver-price") // 覆盖通用路径 ResponseEntity<PriceResponse> getCurrentPrice(); }
然后在配置类中生成这个特定接口的实例就好啦~
备注:内容来源于stack exchange,提问作者PatPanda
相关产品推荐
相关产品推荐

