java - minutes - spring boot scheduled task example
Usando @Scheduled y @EnableScheduling pero da NoSuchBeanDefinitionException (3)
Estoy de acuerdo en que puedes ignorarlo, pero cambiar la gravedad no lo arreglará. Tuve el mismo problema pero estoy usando xml en lugar de anotaciones, y en mi caso sucedió porque no incluí el ejecutor en mi definición de bean. Así que agregar esto lo solucionó:
<task:annotation-driven executor="myExecutor"
scheduler="myScheduler" />
<task:executor id="myExecutor" pool-size="5" />
<task:scheduler id="myScheduler" pool-size="10" />
Espero que ayude.
Saludos.
He seguido ejemplos muy simples en línea para configurar un trabajo cron en Spring, pero sigo recibiendo este error en mi registro de inicio de Tomcat todas las veces:
2015-05-25 00:32:58 DEBUG ScheduledAnnotationBeanPostProcessor:191 -
Could not find default TaskScheduler bean org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type [org.springframework.scheduling.TaskScheduler] is defined
2015-05-25 00:32:58 DEBUG ScheduledAnnotationBeanPostProcessor:202 - Could not
find default ScheduledExecutorService bean
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying
bean of type [org.springframework.scheduling.TaskScheduler] is defined
Y las 2 clases de Java utilizadas para implementar el cron:
1) La clase @Configuration:
@Configuration
@EnableScheduling
public class ClearTokenStoreCronEnable {
final static Logger log =
LoggerFactory.getLogger(ClearTokenStoreCronEnable.class);
private @Autowired TokenStoreRepository tokenStoreRepository;
}
y clase de trabajo Cron:
@Service
public class ClearTokenStoreWorkerService {
final static Logger log = LoggerFactory.getLogger(ClearTokenStoreWorkerService.class);
private @Autowired TokenStoreRepository tokenStoreRepository;
//@Scheduled(fixedDelay=5000)
//run daily at midnight
@Scheduled(cron = "0 0 * * * *")
public void tokenStoreTable() {
log.debug("tokenstore table truncated - start");
tokenStoreRepository.deleteAll();
log.debug("tokenstore table truncated - end");
}
}
Como nota al margen, el trabajo cron se ejecuta a medianoche pero también parece ejecutarse aleatoriamente en otros momentos. No estoy seguro si esto es un error o mi expresión cron es incorrecta: @Scheduled(cron = "0 0 * * * *")
Mi principal preocupación en este momento es ¿por qué recibo los errores ScheduledAnnotationBeanPostProcessor
? Está buscando TaskScheduler y ScheduledExectorService. Solo necesito disparar esto una vez al día. No estoy haciendo ningún procesamiento concurrente o donde necesito múltiples hilos. En última instancia, ¿estos errores son dañinos O debo corregirlos?
de acuerdo con la información de excepción "No se pudo encontrar TaskScheduler bean por defecto", la configuración debe definir "TaskScheduler" en lugar de "Executor"
@Configuration
public class AppContext extends WebMvcConfigurationSupport {
@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler();
}
// Of course , you can define the Executor too
@Bean
public Executor taskExecutor() {
return new SimpleAsyncTaskExecutor();
}
}
EDITAR: la mejor respuesta está aquí y se trata de crear un ejecutor:
@Configuration
@EnableAsync
public class AppContext extends WebMvcConfigurationSupport {
@Bean
public Executor taskExecutor() {
return new SimpleAsyncTaskExecutor();
}
}
ANTERIOR (aún válido, sin embargo):
La excepción NoSuchBeanDefinitionException se registra con una severidad DEBUG y se puede ignorar de forma segura. Si observa el código fuente de ScheduledAnnotationBeanPostProcessor, verá que primero intenta obtener un TaskScheduler, luego un ScheduledExecutorService, luego continúa "cayendo de nuevo al programador predeterminado":
if (this.registrar.hasTasks() && this.registrar.getScheduler() == null) {
Assert.state(this.beanFactory != null, "BeanFactory must be set to find scheduler by type");
try {
// Search for TaskScheduler bean...
this.registrar.setScheduler(this.beanFactory.getBean(TaskScheduler.class));
}
catch (NoUniqueBeanDefinitionException ex) {
throw new IllegalStateException("More than one TaskScheduler exists within the context. " +
"Remove all but one of the beans; or implement the SchedulingConfigurer interface and call " +
"ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback.", ex);
}
catch (NoSuchBeanDefinitionException ex) {
logger.debug("Could not find default TaskScheduler bean", ex);
// Search for ScheduledExecutorService bean next...
try {
this.registrar.setScheduler(this.beanFactory.getBean(ScheduledExecutorService.class));
}
catch (NoUniqueBeanDefinitionException ex2) {
throw new IllegalStateException("More than one ScheduledExecutorService exists within the context. " +
"Remove all but one of the beans; or implement the SchedulingConfigurer interface and call " +
"ScheduledTaskRegistrar#setScheduler explicitly within the configureTasks() callback.", ex);
}
catch (NoSuchBeanDefinitionException ex2) {
logger.debug("Could not find default ScheduledExecutorService bean", ex);
// Giving up -> falling back to default scheduler within the registrar...
}
}
}
Puede eliminar la excepción configurando al menos una gravedad INFO en org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor, como
<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>
cuando se usa logback.
La expresión cron tiene seis campos:
second (0-59), minute (0-59), hour (0-23, 0 = midnight), day (1-31), month (1-12), weekday (1-7, 1 = Sunday)
La sintaxis se puede encontrar en los documentos de cuarzo . No estoy seguro del "?" personaje porque, aunque la página dice
Los ''?'' el carácter está permitido para los campos del día del mes y del día de la semana. Se usa para especificar "ningún valor específico". Esto es útil cuando necesita especificar algo en uno de los dos campos, pero no en el otro.
los ejemplos en esa página realmente usan? incluso cuando el otro campo es *. En mi humilde opinión, todos deberían funcionar con solo *, por lo que para poder ejecutar cada medianoche, la expresión debería ser
0 0 0 * * *