在进行项目开发时,有时需要设置定时任务,spring提供@Scheduled
和@Async
标签可以帮助我们进行定时任务的实现,并且可以保证线程安全。直接上代码:
设置定时时间和配置定时执行的方法
import com.core.context.spring.SpringContextHolder;
import com.faqskill.service.IFaqUpdateToBotService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Map;
@Component
@Lazy(false)
@Slf4j
public class BotTimerTask {
/**
* 每2小时执行一次
*/
@Scheduled(cron="0 0 0/2 * * ? ")
public void runTimer() {
log.info("每两小时一次同步任务启动开始");
//确保需要进行定时任务的接口实例化,IFaqUpdateToBotService是需要定时完成的方法的接口
Map<String, IFaqUpdateToBotService> map = SpringContextHolder.getBeans(IFaqUpdateToBotService.class);
for (IFaqUpdateToBotService timertask : map.values()) {
try {//下面是定时执行的方法
timertask.updateTokens();
timertask.updateTags();
timertask.deleteTags();
timertask.addFaqs();
timertask.updateFaqs();
timertask.deleteFaqs();
timertask.deployFaqs();
} catch (Exception e) {
log.error(timertask.toString() + "botUpdate error", e);
}
}
log.info("每两小时一次同步任务启动结束");
}
}
IFaqUpdateToBotService接口,注意要跟每个需要定时执行的方法加上@Async
标签
@Async
标签就是实现异步操作
import com.base.result.Result;
import org.springframework.scheduling.annotation.Async;
public interface IFaqUpdateToBotService {
@Async
Result updateTokens();
@Async
Result updateTags();
@Async
Result deleteTags();
@Async
Result addFaqs();
@Async
Result deleteFaqs();
@Async
Result updateFaqs();
@Async
Result deployFaqs();
}
SpringContextHolder类
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 以静态变量保存Spring ApplicationContext,可在任意代码中取出ApplicaitonContext.
* @author wy
*/
@Component
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextHolder.applicationContext = applicationContext;
// System.out.println(applicationContext);
}
private static void checkApplicationContext() {
if (applicationContext == null)
throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextUtil");
}
/**
* 取得存储在静态变量中的ApplicationContext.
*/
public static ApplicationContext getApplicationContext() {
checkApplicationContext();
return applicationContext;
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(Class<T> clazz) {
checkApplicationContext();
return (T)applicationContext.getBeansOfType(clazz);
}
public static <T> Map<String, T> getBeans(Class<T> clazz) throws BeansException {
//根据接口类型返回相应的所有bean
checkApplicationContext();
Map<String, T> map = applicationContext.getBeansOfType(clazz);
return map;
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
checkApplicationContext();
try {
return (T) applicationContext.getBean(name);
} catch (Exception e) {
return null;
}
}
}