[英]Prototyped bean not triggering Scheduled method in Spring Boot
我正在使用 Java 17、spring-boot 2.7.3 和 spring 5.3.22 依賴項。
我有如下原型bean:
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class InsertTransactionDetailsByScheduleAPIInteractor
implements InsertTransactionDetailsByScheduleAPIInputBoundary {
private final InsertTransactionsInputBoundary insertTransactionsInputBoundary;
private final RetrieveFileFromSecureFileTransferProtocolInputBoundary retrieveFileFromSecureFileTransferProtocolInputBoundary;
public InsertTransactionDetailsByScheduleAPIInteractor(
final InsertTransactionsInputBoundary insertTransactionsInputBoundaryParam,
@Qualifier(Constants.PROTOTYPE_RETRIEVE_FILE_BEAN_QUALIFIER) final RetrieveFileFromSecureFileTransferProtocolInputBoundary retrieveFileFromSecureFileTransferProtocolInputBoundaryParam) {
super();
this.insertTransactionsInputBoundary = insertTransactionsInputBoundaryParam;
this.retrieveFileFromSecureFileTransferProtocolInputBoundary = retrieveFileFromSecureFileTransferProtocolInputBoundaryParam;
}
/**
* {@inheritDoc}
*/
@Override
// @Scheduled(cron = "* 30 1 * * *", zone = "America/Sao_Paulo")
@Scheduled(initialDelay = 5, fixedRate = 1, timeUnit = TimeUnit.SECONDS)
public void insertTransactionsBySchedule() throws Exception {
this.insertTransactionsInputBoundary.insertTransactions(LocalDate.now(Constants.DEFAULT_ZONE_ID),
this.retrieveFileFromSecureFileTransferProtocolInputBoundary);
}
}
@Configuration
@RefreshScope
class FTPConfiguration {
private final ConsulProperties consulProperties;
public FTPConfiguration(final ConsulProperties consulPropertiesParam) {
super();
this.consulProperties = consulPropertiesParam;
}
@Bean
@RequestScope
@Primary
RetrieveFileFromSecureFileTransferProtocolInputBoundary createRequestScopedRetrieveFileFromSecureFileTransferProtocolBean()
throws Exception {
return this.createRetrieveFileFromSecureFileTransferProtocolBean(true);
}
@Bean
@RequestScope
@Primary
ChannelSftp createRequestScopedSecureFileTransferProtocolChannel() throws JSchException {
return this.createSFTPChannel(true);
}
@Bean(destroyMethod = Constants.FTP_SESSION_BEAN_DESTROY_METHOD)
@RequestScope
@Primary
Session createRequestScopeSecureFileTransferProtocolSession() throws JSchException {
return this.createSFTPSession();
}
@Bean(Constants.PROTOTYPE_RETRIEVE_FILE_BEAN_QUALIFIER)
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
RetrieveFileFromSecureFileTransferProtocolInputBoundary createPrototypeScopedRetrieveFileFromSecureFileTransferProtocolBean()
throws Exception {
return this.createRetrieveFileFromSecureFileTransferProtocolBean(false);
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
ChannelSftp createPrototypeScopedSecureFileTransferProtocolChannel() throws JSchException {
return this.createSFTPChannel(false);
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Session createPrototypeScopedSecureFileTransferProtocolSession() throws JSchException {
return this.createSFTPSession();
}
private RetrieveFileFromSecureFileTransferProtocolInputBoundary createRetrieveFileFromSecureFileTransferProtocolBean(
final boolean isRequestScope) throws Exception {
final var channelSFTP = isRequestScope ? this.createRequestScopedSecureFileTransferProtocolChannel()
: this.createPrototypeScopedSecureFileTransferProtocolChannel();
return new RetrieveFileFromSecureFileTransferProtocolInteractor(channelSFTP,
new ListDirFilesFromSecureFileTransferProtocolInteractor(channelSFTP));
}
private ChannelSftp createSFTPChannel(final boolean isRequestScope) throws JSchException {
final var channel = (isRequestScope ? this.createRequestScopeSecureFileTransferProtocolSession()
: this.createPrototypeScopedSecureFileTransferProtocolSession()).openChannel("sftp");
channel.connect(this.consulProperties.getChannelTimeout());
return (ChannelSftp) channel;
}
private Session createSFTPSession() throws JSchException {
final var session = new JSch().getSession(this.consulProperties.getUsername(), this.consulProperties.getHost(),
this.consulProperties.getPort());
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(this.consulProperties.getFtpPassword());
session.connect(this.consulProperties.getSessionTimeout());
return session;
}
}
我的應用程序 class:
@SpringBootApplication
@EnableCaching
@EnableScheduling
public class Application implements Closeable {
private static ConfigurableApplicationContext run;
public static void main(final String[] args) {
Application.run = SpringApplication.run(Application.class, args);
}
@Override
public void close() {
Application.run.close();
}
}
我將InsertTransactionDetailsByScheduleAPIInteractor
也注釋為原型,以便在每次計划執行時都有一個內部 bean 的新實例,但不知何故,@Scheduled 方法僅在我有一個 singleton InsertTransactionDetailsByScheduleAPIInteractor
bean 時運行,在我的用例中我不能擁有,否則我不會關閉 FTP 連接。 我知道在 Spring 4.3 之前,@Scheduled 方法僅適用於 Singleton bean,但如前所述,我使用的是 Spring 版本 5.3.22。
您正在使用 Spring 但這並不意味着一切都必須由 Spring 管理。 在需要時在 class 中打開 SFTP Session 並在之后關閉它沒有任何問題。 您甚至可以使用 try-with-resources,因為我希望Session
是可以使用的AutoClosable
。
因此,簡而言之,在計划的作業中手動創建您需要的對象,並在作業完成后進行清理。 這樣,您的調度程序可以是常規的 singleton 並在其自身之后進行適當的清理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.