Spring에서 예약 된 작업을 조건부로 활성화 또는 비활성화하는 방법은 무엇입니까?
@Scheduled
주석을 사용하여 Spring에서 cron 스타일 패턴으로 예약 된 작업을 정의하고 있습니다.
cron 패턴은 구성 특성 파일에 저장됩니다. 실제로 두 개의 속성 파일이 있습니다. 하나는 기본 구성이고 다른 하나는 환경에 따라 다르며 (예 : dev, test, prod customer 1, prod customer 2 등) 일부 기본값을 재정의합니다.
${}
스타일 자리 표시자를 사용 하여 속성 파일에서 값을 가져올 수 있도록 스프링 컨텍스트에서 속성 자리 표시 자 빈을 구성했습니다 .
작업 bean은 다음과 같습니다.
@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
}
}
내 컨텍스트 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>
나는 이것을 정말로 좋아한다. 최소한의 XML로 매우 간단하고 깔끔합니다.
그러나 한 가지 더 요구 사항이 있습니다. 이러한 작업 중 일부는 경우에 따라 완전히 비활성화 될 수 있습니다.
그래서 Spring을 사용하여 관리하기 전에 수동으로 만들었고 구성 파일에 cron 매개 변수와 함께 부울 매개 변수가있어 작업을 활성화 해야하는지 여부를 지정합니다.
jobs.mediafiles.imagesPurgeJob.enable=true or false
jobs.mediafiles.imagesPurgeJob.schedule=0 0 0/12 * * ?
이 구성 매개 변수에 따라 Spring 에서이 매개 변수를 사용하여 조건부로 빈을 생성하거나 무시할 수 있습니까?
한 가지 확실한 해결 방법은 절대 평가되지 않는 크론 패턴을 정의하여 작업이 실행되지 않도록하는 것입니다. 그러나 빈은 여전히 생성되고 구성은 약간 모호하므로 더 나은 솔루션이 있어야한다고 생각합니다.
@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...
}
}
}
Spring Boot는 @ConditionalOnProperty를 제공 하는데 , 이는 Spring Boot를 사용한다면 완벽 할 것입니다. 이 주석은 Spring 4.0.0에 도입 된 @Conditional 의 전문화입니다 .
Spring Boot가 아닌 "일반"스프링을 사용한다고 가정하면 Spring Boot의 @ConditionalOnProperty를 모방하는 @Conditional과 함께 사용할 자신의 Condition 구현을 만들 수 있습니다.
일정 방법을 조건별로 서비스 수로 그룹화하고 다음과 같이 초기화 할 수 있습니다.
@Service
@ConditionalOnProperty("yourConditionPropery")
public class SchedulingService {
@Scheduled
public void task1() {...}
@Scheduled
public void task2() {...}
}
속성에서 @EnableScheduling을 토글하려는 경우 @EnableScheduling 주석을 구성 클래스로 이동하고 다음과 같이 @ConditionalOnProperty를 사용하여 Spring Boot에서이를 수행 할 수 있습니다.
@Configuration
@EnableScheduling
@ConditionalOnProperty(prefix = "com.example.scheduling", name="enabled", havingValue="true", matchIfMissing = true)
public class SchedulingConfiguration {
}
이렇게하면 응용 프로그램에 대한 예약이 비활성화됩니다. 이 기능은 응용 프로그램을 한 번만 실행하거나 시작 방법에 따라 예약 할 수있는 상황에서 유용 할 수 있습니다.
wilkinsona의 의견에서 : https://github.com/spring-projects/spring-boot/issues/12682
Your question states to condition the actual creation of the bean. You can do this easily with this parameter by using @Profile if you are using at least Spring 3.1.
See the documentation here: http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/Profile.html
@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;
}
}
The most efficient way to disable @Scheduled in Spring. Just set crone expression like "-". It will disable the @Scheduled.
@Scheduled(cron = "-")
public void autoEvictAllCache() {
LOGGER.info("Refresing the Cache Start :: " + new Date());
activeMQUtility.sendToTopicCacheEviction("ALL");
LOGGER.info("Refresing the Cache Complete :: " + new Date());
}
For more info:
I know my answer is a hack, but giving a valid cron expression that never executes may fix the issue (in the environment specific configuration), Quartz: Cron expression that will never execute
You can also create a Bean based on condition and that Bean can have a Scheduled method.
@Component
@Configuration
@EnableScheduling
public class CustomCronComponent {
@Bean
@ConditionalOnProperty(value = "my.cron.enabled", matchIfMissing = true, havingValue = "true")
public MyCronTask runMyCronTask() {
return new MyCronTask();
}
}
and
@Component
public class MyCronTask {
@Scheduled(cron = "${my.cron.expression}")
public void run() {
String a = "";
}
}
'Programing' 카테고리의 다른 글
상속되는 CSS 속성은 무엇입니까? (0) | 2020.12.12 |
---|---|
스크롤 이벤트가 너무 많이 발생합니다. (0) | 2020.12.12 |
부모 활동을 동적으로 설정 (0) | 2020.12.12 |
SBT에서 Scala 프로젝트에 Java 버전을 적용합니까? (0) | 2020.12.12 |
AutoMapper는 여러 소스에서 변환 (0) | 2020.12.12 |