石英作业配置中的无法解决的循环参考
我正在尝试用石英迁移旧的春季项目到最新的春季启动:
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]
└──<-──┘
I'm trying to migrate old Spring project with Quartz to the latest Spring Boot:
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);
}
}
}
}
When I run the code I get:
The dependencies of some of the beans in the application context form a cycle:
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]
└──<-──┘
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看来您已升级到
Spring Boot 2.6
so “默认情况下禁止参考” ,这是您获得beancurrantyIncreationException
您可以去看的原因这里默认情况下禁止的循环因此,此处的问题是因为在注释@configuration
QuartzConfiguration
时首先创建了Bean。因此,当您致电以获取所有bean namecontext.getBeanDefinitionNames()
这里时,您应该在这里找到QuartConfiguration
bean名称,该名称是contect> context contection.getBean.getBean(bean) )
这使得相同QUARTCONFIGURATION
bean 循环参考beancurrantyIncreationException
被抛出,因此您有两个选择来解决此问题:第一个选项
您可以直接调用
调整器bean
。您无需循环。第二个选项
允许通过在
application.properties
或application.yml
中设置属性来允许循环引用。Looks like you upgraded to
Spring Boot 2.6
so "Circular references are prohibited by default" that is the reason you getBeanCurrentlyInCreationException
you can take a look here circular prohibited by default so the issue here is because first when having annotated@Configuration
forQuartzConfiguration
a bean is created for. So when you call to get all bean namescontext.getBeanDefinitionNames()
here you should find theQuartConfiguration
bean name which is being a referenced bycontext.getBean(bean)
this makes a circular reference for the sameQuartConfiguration
bean then theBeanCurrentlyInCreationException
is thrown, so you have two options to solve this:First option
You might call the
Scheduler bean
directly. You don't have the need to loop.Second option
Allow circular references by setting a property in
application.properties
orapplication.yml
which the property is:无论您是否初始化,您都可以将所有豆类名称
。您可以自动调整器。
You are getting all beans name no matter if they are initialized or not
You could autowire Scheduler.