gpt4 book ai didi

java - Spring Boot如何正确使用@PostConstruct

转载 作者:行者123 更新时间:2023-12-05 04:45:20 26 4
gpt4 key购买 nike

Spring boot 2.5.4 我第一次在我的服务类中使用@PostConstruct。如下:-

   @Slf4j
@Service
@AllArgsConstructor

public class FileMonitorService {

private final AppProperties appProperties;

private final WatchService watchService;

private final RestTemplate restTemplate;

@PostConstruct
@Async
public void startMonitoring() {
FileUtils.setAppProperties(appProperties);
FileUtils.setRestTemplate(restTemplate);
FileUtils.readFilesForDirectory();
log.info("START_MONITORING");
try {
WatchKey key;
while ((key = watchService.take()) != null) {
for (WatchEvent<?> event : key.pollEvents()) {
log.info("Event kind: {}; File affected: {}", event.kind(), event.context());
if((event.kind() == StandardWatchEventKinds.ENTRY_CREATE ||
event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) &&
event.context().toString().contains(".xml")){
try {
restTemplateRequest(event.context().toString()+" processing");
FileUtils.readXml(Path.of(FileUtils.getFileAbsolutePath(appProperties.getDataIn()),
event.context().toString()));
}catch (Exception e){
log.error("startMonitoring Exception: "+e.getMessage());
}
}
}
key.reset();
}
} catch (InterruptedException e) {
log.warn("startMonitoring: interrupted exception for monitoring service: "+e.getMessage());
}
}
}

此方法会在应用启动后立即调用。这是我在应用程序启动后立即处理所有文件的要求。我有如下 Controller :-

@RestController
@RequestMapping("/xml")
public class FileController {

@Autowired
FileMonitorService fileMonitorService;

@SneakyThrows
@GetMapping("/restart")
public String restartFileMonitoring(){
fileMonitorService.startMonitoring();
return "File monitoring restarted started successfully";
}
}

我的应用程序在端口 8080 上启动,没有任何异常。但是当我调用这个端点时 localhost:8080/xml/restart

无法访问。如果我注释掉 @PostConstruct 然后我可以调用终点。我很困惑如何正确使用此注释。我的代码有什么问题?

更新信息:-

    :: Spring Boot ::                (v2.5.4)

2021-09-14 18:23:21.521 INFO 71192 --- [ main] c.f.i.task.BatchProcessorApplication : Starting BatchProcessorApplication using Java 14.0.2 on dev with PID 71192 (/home/dev/Desktop/batch-processor/batch-processor/target/classes started by dev in /home/dev/Desktop/batch-processor/batch-processor)
2021-09-14 18:23:21.523 INFO 71192 --- [ main] c.f.i.task.BatchProcessorApplication : No active profile set, falling back to default profiles: default
2021-09-14 18:23:22.485 INFO 71192 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-09-14 18:23:22.495 INFO 71192 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-09-14 18:23:22.495 INFO 71192 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.52]
2021-09-14 18:23:22.564 INFO 71192 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-09-14 18:23:22.564 INFO 71192 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 988 ms
File to monitor: /home/dev/Desktop/batch-processor/batch-processor/data/in
2021-09-14 18:23:22.647 INFO 71192 --- [ main] c.f.i.task.config.FileMonitorConfig : MONITORING_DIR: /home/dev/Desktop/batch-processor/batch-processor/data/in/
2021-09-14 18:23:22.667 INFO 71192 --- [ main] c.f.i.task.service.FileMonitorService : START_MONITORING

这是我运行应用程序时的日志。调试后我发现 while ((key = watchService.take()) != null) { 调用永远不会返回,直到我复制一些 XML 文件作为这个应用程序处理 xml 文件。然后我复制监控目录中的任何 xml 文件。我期待 @Async 它将以异步模式在后台线程中运行。如何在后台线程中监控这个目录?所以这个方法的调用者不会被阻塞。

最佳答案

PostContstruct 语义


PostConstruct 注释是 JSR 330 (Dependency Injection) 的一部分并且不是 Spring 自定义注释。

注解规范规定被注解的方法必须在服务被注入(inject)上下文或翻译成服务之前运行。

Spring 支持 PostConstruct 生命周期 Hook ,允许在 bean 初始化后执行额外的初始化后操作,即它已注入(inject)所有依赖项。

异步语义


另一方面,Async 注释是 Spring 特定的注释,允许将方法或类型标记为异步执行的候选者。

备选


如果您有兴趣在应用程序启动时启动后台进程,您应该更好地使用应用程序生命周期事件,更具体地说,ApplicationReadyEvent 来旋转您的监控 Activity :

@Slf4j
@Service
@AllArgsConstructor
public class FileMonitorService {

private final AppProperties appProperties;

private final WatchService watchService;

private final RestTemplate restTemplate;

@EventListener(ApplicationReadyEvent.class)
@Async
public void startMonitoring() {
// ...
}
}

不要忘记在 Spring Boot 配置类型上添加 @EnableAsync 注释以激活异步处理功能。

关于java - Spring Boot如何正确使用@PostConstruct,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69175260/

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