我正在尝试创建一个SpringBoot应用程序,该应用程序将使用来自第三方REST API的数据,并根据事件/对该数据的更改将Websocket通知推送到我自己的客户端。我消耗的数据经常变化,有时每秒变化几十次(加密货币价格波动与此数据的行为类似)。我希望以固定的间隔(例如每1-10秒)重复调用API,监视某些事件/更改并在发生这些事件时触发Websocket推送。
我已经能够构建一个简单的Spring Boot应用程序,它可以通过以下指南推送Websocket Notifications并使用API:
问题:我只能让应用程序从API请求一次数据。我花了好几个小时搜索我能想到的“Spring RestTemplate多次/重复/持续调用”的每个变体,但我找不到解决我特定用途的解决方案。我发现的最接近的例子使用了重试,但即使那些最终也会放弃。我希望我的应用程序不断请求此数据,直到我关闭应用程序。我知道我可以将它包装在while(true)
语句或类似的东西中,但是对于像SpringBoot这样的框架来说这似乎并不合适,并且在尝试实例化RestTemplate时仍然存在问题。
如何实现RESTful API资源的持久查询?
以下是我在Application类中的内容
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableScheduling
public class Application {
private static final String API_URL = "http://hostname.com/api/v1/endpoint";
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}
@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Response response= restTemplate.getForObject(API_URL, Response.class);
System.out.println(response.toString());
};
}
}
CommandLineRunner
每个应用程序启动只运行一次。相反,您希望使用@Scheduled
注释以固定间隔执行重复操作,例如
@Scheduled(fixedDelay = 1000L)
public void checkApi() {
Response response = restTemplate.getForObject(API_URL, Response.class);
System.out.println(response.toString())
}
它不需要是一个Bean
,它只是一个简单的方法。有关https://spring.io/guides/gs/scheduling-tasks/的更多信息,请参阅Spring指南
在SpringConfig类或Main类上添加@EnableScheduling
注释。
您可以使用Scheduled fixedDelay或fixedRate
@Scheduled(fixedDelay = 10000)
public void test() {
System.out.println("Scheduler called.");
}
要么
@Scheduled(fixedRate = 10000)
public void test() {
System.out.println("Scheduler called.");
}
fixedDelay和fixedRate之间的区别:
fixedDelay - 确保执行任务的结束时间与下次执行任务的开始时间之间有n毫秒的延迟。
fixedRate - 每n毫秒运行一次计划任务。
理想情况下,您应该在application.properties文件中将fixedDelay或fixedRate值外部化:
@Scheduled(fixedDelayString = "${scheduler.fixed.delay}")
public void test() {
System.out.println("Scheduler called.");
}
在你的application.properties文件中添加以下配置:
scheduler.fixed.delay = 10000
希望这可以帮助。