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[/span
@Async[/span
public void startMonitoring() {
FileUtils.setAppProperties(appProperties)。
FileUtils.setRestTemplate(restTemplate)。
FileUtils.readFilesForDirectory()。
log.info("START_MONITORING"/span>)。
try {
WatchKey鍵。
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.warning("startMonitoring: interrupted exception for monitoring service: " e.getMessage())。
}
}
這個方法在應用程式啟動時就被呼叫。這是我的要求,要在應用程式啟動后立即處理所有檔案。我有如下的控制器:
@RestController。
@RequestMapping("/xml")
public class FileController {
@Autowired
FileMonitorService fileMonitorService。
@SneakyThrows[/span
@GetMapping("/restart")
public String restartFileMonitoring{
fileMonitorService.startMonitoring()。
return "檔案監控重啟開始成功"。
}
我的應用程式在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/target/classes started by dev in /home/dev/Desktop/batch-Processor)
2021-09-14 18:23:21。 523 INFO 71192 -- [main] c.f.i.task.BatchProcessorApplication : 沒有活動的組態檔設定,回落到默認組態檔。default 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 。啟動服務 [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
要監控的檔案。/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它將在后臺執行緒中以異步模式運行。如何在后臺執行緒中監控這個目錄?這樣這個方法的呼叫者就不會被阻塞了。
uj5u.com熱心網友回復:
PostContstruct語意
PostConstruct注解是JSR 330(依賴注入)的一部分,而不是Spring自定義注解。
注解規范規定,被注解的方法必須在被注入背景關系的服務或翻譯成服務之前運行。
Spring支持PostConstruct生命周期鉤子,允許在Bean被初始化后執行額外的初始化操作,也就是說,它的所有依賴被注入。
Async語意
另一方面,
Async注解是一個Spring特定的注解,允許將一個方法或一個型別標記為異步執行的候選物件。
替代方案
在您對只要應用程式啟動就會啟動后臺行程感興趣的情況下,您最好使用應用程式生命周期事件,特別是ApplicationReadyEvent來啟動您的監控活動。
@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注解,以激活異步處理功能。
uj5u.com熱心網友回復:
對于你的情況,你不需要使用@PostConstruct,這就是為什么它在移除@PostConstruct后還能作業的原因
為了簡化,@PostConstruct被認為是一個類的空建構式,但它確保所有的Bean在被呼叫前已經被加載。轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/307782.html
標籤:
上一篇:多個將被使用的@ConditionalOnMissingBeanbean
下一篇:在一個選擇查詢中寫一個連接子查詢
