tareas quartz programadas minuto job ejemplo configurar cada java spring hibernate spring-boot quartz-scheduler

java - programadas - Spring Boot: uso de @Service en la ejecución del trabajo de Quartz



spring quartz ejemplo (2)

En una aplicación, como la convertí de una aplicación web Spring clásica (implementada en un sistema Tomcat) a una aplicación Spring Boot (V1.2.1), tengo el problema de que los trabajos programados basados ​​en Quartz ya no funcionan.

Programa estos trabajos de Quartz como este:

// My own Schedule object which holds data about what to schedule when Schedule schedule = scheduleService.get(id of the schedule); String scheduleId = schedule.getId(); JobKey jobKey = new JobKey(scheduleId); TriggerKey triggerKey = new TriggerKey(scheduleId); JobDataMap jobData = new JobDataMap(); jobData.put("scheduleId", scheduleId); JobBuilder jobBuilder = JobBuilder.newJob(ScheduledActionRunner.class) .withIdentity(jobKey) .withDescription(schedule.getName()) .usingJobData(jobData); JobDetail job = jobBuilder.build(); TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger() .forJob(jobKey) .withIdentity(triggerKey) .withDescription(schedule.getName()); triggerBuilder = triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(schedule.toCronExpression())); Trigger trigger = triggerBuilder.build(); org.quartz.Scheduler scheduler = schedulerFactoryBean.getScheduler(); scheduler.scheduleJob(job, trigger);

ScheduledActionRunner :

@Component public class ScheduledActionRunner extends QuartzJobBean { @Autowired private ScheduleService scheduleService; public ScheduledActionRunner() { } @Override public void executeInternal(final JobExecutionContext context) throws JobExecutionException { SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); final JobDataMap jobDataMap = context.getMergedJobDataMap(); final String scheduleId = jobDataMap.getString("scheduleId"); final Schedule schedule = scheduleService.get(scheduleId); // here it goes BANG since scheduleService is null } }

ScheduleService es un servicio clásico de Spring que obtiene datos de Hibernate. Como dije antes, funcionó bien hasta que me mudé a Spring Boot.

Cuando implementé este código con la aplicación clásica de Spring, SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); hizo el truco para encargarse de autocablear el servicio.

¿Qué se necesita para que esto vuelva a funcionar en el entorno Spring Boot?

Editar:

Al final, decidí alejarme del uso de Quartz a favor de Spring''s ThreadPoolTaskScheduler. El código se simplificó mucho y funciona como se esperaba.


SpringBeanAutowiringSupport utiliza el contexto de la aplicación web, que no está disponible en su caso. Si necesita un grano manejado por resorte en el cuarzo, debe usar el soporte de cuarzo provisto por la primavera. Esto le dará acceso completo a todos los beans administrados. Para obtener más información, consulte la sección de cuarzo en los documentos de primavera en http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html . Consulte también el siguiente ejemplo de uso de cuarzo con frijoles administrados por resorte. El ejemplo se basa en tu código. Por lo tanto, puede cambiar el primer fragmento de código (donde se realiza la inicialización de cuarzo) con alternativas de muelles alternativos.

Crear detalle de trabajo de fábrica

@Component public class ScheduledActionRunnerJobDetailFactory extends JobDetailFactoryBean { @Autowired private ScheduleService scheduleService; @Override public void afterPropertiesSet() { setJobClass(ScheduledActionRunner.class); Map<String, Object> data = new HashMap<String, Object>(); data.put("scheduleService", scheduleService); setJobDataAsMap(data); super.afterPropertiesSet(); } }

Crear la fábrica de disparadores

@Component public class ActionCronTriggerFactoryBean extends CronTriggerFactoryBean { @Autowired private ScheduledActionRunnerJobDetailFactory jobDetailFactory; @Value("${cron.pattern}") private String pattern; @Override public void afterPropertiesSet() throws ParseException { setCronExpression(pattern); setJobDetail(jobDetailFactory.getObject()); super.afterPropertiesSet(); } }

Y finalmente crea el SchedulerFactory

@Component public class ActionSchedulerFactoryBean extends SchedulerFactoryBean { @Autowired private ScheduledActionRunnerJobDetailFactory jobDetailFactory; @Autowired private ActionCronTriggerFactoryBean triggerFactory; @Override public void afterPropertiesSet() throws Exception { setJobDetails(jobDetailFactory.getObject()); setTriggers(triggerFactory.getObject()); super.afterPropertiesSet(); } }


Mi respuesta no coincide por completo con su pregunta, pero Spring le muestra otra habilidad: iniciar el programador basado en cron-expression en cualquier servicio.

Usando Spring.Boot puedes configurar tu aplicación para usar el programador simplemente colocando

@EnableScheduling public class Application{ ....

Después de eso simplemente coloque la siguiente anotación en public método public (!) De @Service

@Service public class MyService{ ... @Scheduled(cron = "0 * * * * MON-FRI") public void myScheduledMethod(){ .... }