requestmapping que mvc modelo modelandview formulario español ejemplo arquitectura java spring cron scheduled-tasks

java - que - ¿Cómo habilitar o deshabilitar de manera condicional los trabajos programados en Spring?



spring mvc español (7)

Estoy definiendo trabajos programados con patten de estilo cron en Spring, usando la anotación @Scheduled .

El patrón cron se almacena en un archivo de propiedades config. En realidad, hay dos archivos de propiedades: una configuración predeterminada y una configuración de perfil que depende del entorno (p. Ej., Desarrollador, prueba, cliente prod 1, cliente prod 2, etc.) y anula algunos de los valores predeterminados.

Configuré un bean de marcador de posición de propiedad en mi contexto de primavera que me permite usar marcadores de posición de estilo ${} para importar valores de mis archivos de propiedades.

Los beans de trabajo se ven así:

@Component public class ImagesPurgeJob implements Job { private Logger logger = Logger.getLogger(this.getClass()); @Override @Transactional(readOnly=true) @Scheduled(cron = "${jobs.mediafiles.imagesPurgeJob.schedule}") public void execute() { //Do something //can use DAO or other autowired beans here } }

Partes relevantes de mi contexto XML:

<!-- Enable configuration of scheduled tasks via annotations --> <task:annotation-driven/> <!-- Load configuration files and allow ''${}'' style placeholders --> <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:config/default-config.properties</value> <value>classpath:config/environment-config.properties</value> </list> </property> <property name="ignoreUnresolvablePlaceholders" value="true"/> <property name="ignoreResourceNotFound" value="false"/> </bean>

Realmente me gusta esto. Es bastante simple y limpio con XML mínimo.

Sin embargo, tengo un requisito más: algunos de estos trabajos pueden estar totalmente deshabilitados en algunos casos.

Entonces, antes de usar Spring para administrarlos, los creé manualmente y hay un parámetro booleano junto con el parámetro cron en los archivos de configuración, para especificar si el trabajo debe estar habilitado o no:

jobs.mediafiles.imagesPurgeJob.enable=true or false jobs.mediafiles.imagesPurgeJob.schedule=0 0 0/12 * * ?

¿Cómo puedo usar este parámetro en Spring para crear condicionalmente o simplemente ignorar el bean, dependiendo de este parámetro de configuración?

Una solución obvia sería definir un patrón cron que nunca se evaluaría, por lo que el trabajo nunca se ejecuta. Pero el bean aún se crearía y la configuración sería un poco oscura, por lo que creo que debe haber una solución mejor.

Alguna idea ?


Puede agrupar los métodos de programación por condiciones en la cantidad de servicios e iniciarlos de esta manera:

@Service @ConditionalOnProperty("yourConditionPropery") public class SchedulingService { @Scheduled public void task1() {...} @Scheduled public void task2() {...} }



Si está buscando alternar @EnableScheduling desde una propiedad, puede hacer esto en Spring Boot moviendo la anotación @EnableScheduling a una clase de configuración y usar @ConditionalOnProperty de la siguiente manera:

@Configuration @EnableScheduling @ConditionalOnProperty(prefix = "com.example.scheduling", name="enabled", havingValue="true", matchIfMissing = true) public class SchedulingConfiguration { }

Esto deshabilitará la programación de la aplicación. Esto puede ser útil en una situación en la que desee poder ejecutar la aplicación una vez o programarla según cómo se inicie.

Del comentario de wilkinsona aquí: https://github.com/spring-projects/spring-boot/issues/12682


Spring Boot proporciona @ConditionalOnProperty , que sería perfecto si usa Spring Boot. Esta anotación es una especialización de @Conditional , presentada con Spring 4.0.0.

Asumiendo que solo está usando un resorte "normal" y no un Spring Boot, podría crear su propia implementación de Condición para usar con @Conditional que imitaría a @ConditionalOnProperty de Spring Boot.



@Component public class CurrencySyncServiceImpl implements CurrencySyncService { private static Boolean isEnableSync; /** * Currency Sync FixedDelay in minutes */ private static Integer fixedDelay; @Transactional @Override @Scheduled(fixedDelayString = "#{${currency.sync.fixedDelay}*60*1000}") public void sync() { if(CurrencySyncServiceImpl.isEnableSync) { //Do something //you can use DAO or other autowired beans here. } } @Value("${currency.sync.fixedDelay}") public void setFixedDelay(Integer fixedDelay) { CurrencySyncServiceImpl.fixedDelay = fixedDelay; } @Value("${currency.sync.isEnable}") public void setIsEnableSync(Boolean isEnableSync) { CurrencySyncServiceImpl.isEnableSync = isEnableSync; } }


@Component public class ImagesPurgeJob implements Job { private Logger logger = Logger.getLogger(this.getClass()); @Value("${jobs.mediafiles.imagesPurgeJob.enable}") private boolean imagesPurgeJobEnable; @Override @Transactional(readOnly=true) @Scheduled(cron = "${jobs.mediafiles.imagesPurgeJob.schedule}") public void execute() { //Do something //can use DAO or other autowired beans here if(imagesPurgeJobEnable){ Do your conditional job here... } } }