Как мне передать данные методу, запускаемому как MethodInvokingJobDetailFactoryBean?

#java #spring #quartz-scheduler

#java #spring #quartz-планировщик

Вопрос:

Что я действительно пытаюсь сделать, так это создать задание Quartz, которое не выполняется одновременно, но также может получить доступ к JobExecutionContext , чтобы получить previousFireTime . Вот мой объект:

 // imports...

public class UtilityObject {

    private SomeService someService;

    @Autowired
    public UtilityObject(SomeService someService) {
        this.someService = someService;
    }

    public void execute(JobExecutionContext ctx) throws JobExecutionException {
        Date prevDate = ctx.getPreviousFireTime();

        // rest of the code...
    }
}
  

И вот как я настроил свой компонент:

 <bean name="utilityBean" class="UtilityObject" />

<bean id="utilityJob"
    class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
   <property name="targetOjbect" ref="utilityBean" />
   <property name="targetMethod" value="execute" />
   <property name="concurrent" value="false" />
</bean>

<bean name="utilityTrigger"
    class="org.springframework.scheduling.quartz.SimpleTriggerBean">
    <property name="jobDetail" ref="utilityJob" />
    <property name="startDelay" value="5000" />
    <property name="repeatInterval" value="20000" />
</bean>
  

Когда я пытаюсь запустить это, происходит сбой во время создания компонента с

Исключение noSuchMethod: UtilityJob.execute()

Есть идеи?

Решение:

После прочтения ответа Скаффмана я смог заставить свое решение работать. Используя триггер, который у меня был, я знал, что имя было, и выяснил, что группа по умолчанию была «DEFAULT». Я расширил QuartzJobBean класс моего класса, а затем добавил этот фрагмент кода:

 protected void executeInternal(JobExecutionContext ctx) 
               throws JobExecutionException {
    boolean isRunning = 
           (ctx.getScheduler().getTriggerState("utilityTrigger", "DEFAULT") ==
               Trigger.STATE_BLOCKED);

    if (isRunning) {
        // run the job
    }
} 
  

Извините за странное форматирование; это несколько длинных строк!

Ответ №1:

Можно передавать аргументы в MethodInvokingJobDetailFactoryBean таким же образом, как в spring MethodInvokingFactoryBean , используя свойство arguments.

Например:

 <bean id="myJob"
      class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject" ref="myBean" />
    <property name="targetMethod" value="myMethod" />
    <property name="arguments">
        <list>
            <value>greetings</value>
            <ref bean="anotherBean"/>
        </list>
    </property>
</bean>
  

Ответ №2:

MethodInvokingJobDetailFactoryBean удобный, но примитивный — он может выполнять только общедоступные методы без аргументов.

Если для вашей работы необходим доступ к Quartz API, тогда вам нужно будет использовать JobDetailBean и QuartzJobBean вместо MethodInvokingJobDetailFactoryBean . Инструкции о том, как это сделать, см. в документах. При запуске QuartzJobBean передается текущее JobExecutionContext значение.

Комментарии:

1. Спасибо. Я изменяю свой вопрос, чтобы включить ответ, к которому я в конечном итоге пришел после прочтения вашего ответа.