I am defining scheduled jobs with cron style patterns in Spring, using the @Scheduled
annotation.
The cron pattern is stored in a config properties file. Actually there are two properties files: one default config, and one profile config that is environment dependent (e.g. dev, test, prod customer 1, prod customer 2 etc.) and overrides some of the default values.
I configured a property placeholder bean in my spring context which allows me to use ${}
style placeholders to import values from my properties files.
The job beans looks like this:
@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
}
}
Relevant parts of my context 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>
I really like this. It's quite simple and clean with minimal XML.
However I have one more requirement: some of these jobs can be totally disabled in some cases.
So, before I used Spring to manage them I created them manually and there is a boolean parameter along with the cron parameter in the config files, to specify if the job has to be enabled or not:
jobs.mediafiles.imagesPurgeJob.enable=true or false
jobs.mediafiles.imagesPurgeJob.schedule=0 0 0/12 * * ?
How can I use this parameter in Spring to conditionally create or just plainly ignore the bean, depending on this config parameter?
One obvious workaround would be to define a cron pattern that would never evaluate, so the job is never executed. But the bean would still be created and the config would be a bit obscure, so I feel there must be a better solution.
@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...
}
}
}