[英]Unresolvable circular reference in Quartz job configuration
我正在嘗試將使用 Quartz 的舊 Spring 項目遷移到最新的 Spring 引導:
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzConfiguration implements InitializingBean {
public static final Logger LOGGER = LoggerFactory.getLogger(QuartzConfiguration.class);
public static final String JOB_KEY = "FinalizationJob";
public static final String KEY = JOB_KEY + "_Trigger";
private ApplicationContext context;
@Autowired
public QuartzConfiguration(ApplicationContext context) {
this.context = context;
}
@Bean(name = "finalJobDetail")
public JobDetail batchExpireUpdateJobDetail() {
return JobBuilder.newJob(BatchExpireUpdateJob.class)
.withIdentity(JobKey.jobKey(JOB_KEY))
.storeDurably()
.build();
}
@Override
public void afterPropertiesSet() {
Trigger newTrigger = newTrigger()
.forJob(JOB_KEY)
.withIdentity(triggerKey(KEY))
.withSchedule(repeatSecondlyForever(100))
.build();
try {
Scheduler obj = getSchedulerInstanceFromApplicationContext();
if (obj.checkExists(triggerKey(KEY))) {
obj.rescheduleJob(triggerKey(KEY), newTrigger);
} else {
obj.scheduleJob(newTrigger);
}
} catch (SchedulerException | NullPointerException e) {
LOGGER.error("error {}", JOB_KEY, e);
}
}
private Scheduler getSchedulerInstanceFromApplicationContext() {
Scheduler obj = null;
String [] beans = context.getBeanDefinitionNames();
for (String bean: beans) {
if (context.getBean(bean) instanceof Scheduler) {
obj = (Scheduler) context.getBean(bean);
break;
}
}
return obj;
}
@DisallowConcurrentExecution
private static class BatchExpireUpdateJob implements Job {
private DatabaseService databaseService;
@Autowired
public BatchExpireUpdateJob(DatabaseService databaseService) {
this.databaseService = databaseService;
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
try {
LOGGER.info("Updating status");
databaseService.updateStatus();
} catch (Exception e) {
LOGGER.error("Error ", e);
throw new JobExecutionException(e);
}
}
}
}
當我運行代碼時,我得到:
應用上下文中一些bean的依賴形成了一個循環:
Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'quartzConfiguration': Requested bean is currently in creation: Is there an unresolvable circular reference?
┌──->──┐
| QuartzConfiguration defined in file C:\......\QuartzConfiguration.class]
└──<-──┘
看起來你升級到Spring Boot 2.6
所以“默認情況下禁止循環引用”這就是你得到BeanCurrentlyInCreationException
的原因你可以看看這里循環默認禁止所以這里的問題是因為首先為QuartzConfiguration
注釋@Configuration
一個 bean是為。 因此,當您在這里調用獲取所有 bean 名稱context.getBeanDefinitionNames()
時,您應該找到由context.getBean(bean)
引用的QuartConfiguration
bean 名稱,這會對同一個QuartConfiguration
bean 進行循環引用,然后拋出BeanCurrentlyInCreationException
,所以你有兩種選擇來解決這個問題:
第一個選項
您可以直接調用Scheduler bean
。 你不需要循環。
private Scheduler getSchedulerInstanceFromApplicationContext() {
return context.getBean(Scheduler.class);
}
第二種選擇
通過在application.properties
或application.yml
中設置屬性來允許循環引用,該屬性是:
spring.main.allow-circular-references=true
無論它們是否已初始化,您都將獲得所有 bean 名稱
String [] beans = context.getBeanDefinitionNames();
您可以自動裝配調度程序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.