簡體   English   中英

Quartz 作業配置中無法解析的循環引用

[英]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.propertiesapplication.yml中設置屬性來允許循環引用,該屬性是:

spring.main.allow-circular-references=true

無論它們是否已初始化,您都將獲得所有 bean 名稱

String [] beans = context.getBeanDefinitionNames();

您可以自動裝配調度程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2025 STACKOOM.COM