我有一个Java Spring Boot应用程序,该应用程序具有一个Scheduler,该Scheduler从Service调用异步任务。该任务需要几分钟(通常3-5分钟)才能完成。
通过从Spring Boot Controller调用API,也可以通过UI应用程序调用服务中的相同异步方法。
代码:
计划程序
@Component
public class ScheduledTasks {
@Autowired
private MyService myService;
@Scheduled(cron = "0 0 */1 * * ?")
public void scheduleAsyncTask() {
myService.doAsync();
}
}
服务
@Service
public class MyService {
@Async("threadTaskExecutor")
public void doAsync() {
//Do Stuff
}
}
控制器
@CrossOrigin
@RestController
@RequestMapping("/mysrv")
public class MyController {
@Autowired
private MyService myService;
@CrossOrigin
@RequestMapping(value = "/", method = RequestMethod.POST)
public void postAsyncUpdate() {
myService.doAsync();
}
}
调度程序每小时运行一次异步任务,但是用户也可以从UI手动运行它。
但是,如果异步方法已经在执行过程中,我不希望它再次运行。
为此,我在数据库中创建了一个表,其中包含一个标志,该标志在方法运行时会亮起,然后在方法完成后将其关闭。
在我的服务类别中是这样的:
@Autowired
private MyDbRepo myDbRepo;
@Async("threadTaskExecutor")
public void doAsync() {
if (!myDbRepo.isRunning()) {
myDbRepo.setIsRunning(true);
//Do Stuff
myDbRepo.setIsRunning(false);
} else {
LOG.info("The Async task is already running");
}
}
现在,问题在于该标志有时由于各种原因(应用程序重新启动,其他一些应用程序错误等)而被卡住
因此,我想在每次部署Spring Boot应用程序时以及每次重新启动时在DB中重置该标志。
我该怎么做?在Spring Boot应用程序启动后,是否有某种方法可以运行方法,从那里我可以从Repo调用方法来取消设置数据库中的标志?
答案 0 :(得分:6)
例如在https://www.baeldung.com/running-setup-logic-on-startup-in-spring
中检查@PostConstruct答案 1 :(得分:1)
如果要在整个应用程序启动并准备好使用后在示例from下做一些事情
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class ApplicationStartup
implements ApplicationListener<ApplicationReadyEvent> {
/**
* This event is executed as late as conceivably possible to indicate that
* the application is ready to service requests.
*/
@Override
public void onApplicationEvent(final ApplicationReadyEvent event) {
// here your code ...
return;
}
} // class
如果在创建单个bean之后足以挂接,请按照@loan M的建议使用@PostConstruct
答案 2 :(得分:0)
在特定情况下,您需要在应用程序部署后重置数据库,因此,实现此目的的最佳方法是使用 Spring CommandLineRunner 。
Spring Boot为CommanLineRunner接口提供了具有回调run()方法的方法,该方法可以在应用程序启动时调用 在实例化Spring应用程序上下文之后。
CommandLineRunner bean可以在同一应用程序上下文中定义,并且可以使用@Ordered接口或@Order进行订购。 注释。
@Component
public class CommandLineAppStartupRunnerSample implements CommandLineRunner {
private static final Logger LOG =
LoggerFactory.getLogger(CommandLineAppStartupRunnerSample .class);
@Override
public void run(String...args) throws Exception {
LOG.info("Run method is executed");
//Do something here
}
}
从站点引荐的答案:https://www.baeldung.com/running-setup-logic-on-startup-in-spring