Spring Boot如何读取外部API属性存入应用上下文实现全局可用
实现方案
下面分别给出你要求的启动预加载存入Spring上下文的方案,以及其他更灵活的可选优化方案:
方案1:启动预加载为Spring Bean(推荐符合Spring规范)
该方案实现简单,返回值直接纳入Spring容器管理,全局可直接注入使用:
- 首先将RestTemplate注册为Bean,避免每次调用重复实例化:
@Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }
- 启动时调用外部API,将返回的字符串注册为Spring Bean:
@Configuration public class ExternalApiConfig { // 相关配置可以写到application.yml/properties里,避免硬编码 @Value("${external.api.test.id:1}") private String apiId; @Value("${external.api.test.url:http://localhost:7070/api/test/{id}}") private String apiUrl; @Autowired private RestTemplate restTemplate; @Bean("reqVal") public String getReqVal() { // 可自定义重试逻辑避免偶发API调用失败导致应用启动异常 int retryCount = 3; while (retryCount > 0) { try { HttpEntity<Void> entity = new HttpEntity<>(new HttpHeaders()); ResponseEntity<String> result = restTemplate.exchange(apiUrl, HttpMethod.GET, entity, String.class, apiId); JSONObject jsonResponse = new JSONObject(result.getBody()); return jsonResponse.getString("reqKey"); } catch (Exception e) { retryCount--; if (retryCount == 0) { // 可选择抛出异常终止启动,或者返回默认值不影响启动 throw new RuntimeException("外部API调用失败,无法获取reqVal", e); // 容错写法:return "default_value"; } try { Thread.sleep(1000); } catch (InterruptedException ex) { Thread.currentThread().interrupt(); } } } return "default_value"; } }
- 任意位置注入使用即可:
@Service public class YourBusinessService { @Autowired @Qualifier("reqVal") private String reqVal; public void doBusiness() { // 直接使用预加载的字符串 System.out.println(reqVal); } }
方案2:存入静态常量(无需注入可直接调用)
如果不想依赖Spring注入,也可以将值存在静态变量中全局调用:
@Component public class ExternalApiConstant { public static String REQ_VAL; @Value("${external.api.test.id:1}") private String apiId; @Value("${external.api.test.url:http://localhost:7070/api/test/{id}}") private String apiUrl; @Autowired private RestTemplate restTemplate; @PostConstruct public void initReqVal() { HttpEntity<Void> entity = new HttpEntity<>(new HttpHeaders()); ResponseEntity<String> result = restTemplate.exchange(apiUrl, HttpMethod.GET, entity, String.class, apiId); JSONObject jsonResponse = new JSONObject(result.getBody()); REQ_VAL = jsonResponse.getString("reqKey"); } }
使用时直接调用静态变量即可:ExternalApiConstant.REQ_VAL
可选优化方案
如果后续API返回值可能会调整,但变化频率极低,可以加本地缓存替代启动一次性加载,无需重启应用就能自动获取更新后的值:
@Service public class ExternalApiService { private final LoadingCache<String, String> reqValCache; public ExternalApiService(@Value("${external.api.test.id:1}") String apiId, @Value("${external.api.test.url:http://localhost:7070/api/test/{id}}") String apiUrl, RestTemplate restTemplate) { // 缓存1小时过期,到期自动调用接口刷新值 this.reqValCache = Caffeine.newBuilder() .expireAfterWrite(1, TimeUnit.HOURS) .build(key -> { HttpEntity<Void> entity = new HttpEntity<>(new HttpHeaders()); ResponseEntity<String> result = restTemplate.exchange(apiUrl, HttpMethod.GET, entity, String.class, apiId); JSONObject jsonResponse = new JSONObject(result.getBody()); return jsonResponse.getString("reqKey"); }); } public String getReqVal() { return reqValCache.get("reqKey"); } }
使用时注入该Service调用getReqVal()即可,第一次调用会请求API,后续都走缓存。
内容的提问来源于stack exchange,提问作者maniprav
相关产品推荐
相关产品推荐

