Study background
Learning should be purposeful, aimless learning will make you grow slowly. My learning background is that the upstream system needs to push their commodity data to our system (about 4 million data), and we need to push this part of data to the ERP system when we save it. Due to the large amount of data, it is inevitable to encounter a series of problems such as service connection timeout in the process of push. In case of problems, we need to record the data that failed to push and deal with this part of data in the future.
There are two ways to process failed data: manual push; Scheduled task push. Manual push is too annoying, so choose timed task push. The leader also required the timing task to be able to control the switch and the time and frequency of push, so the dynamic timing task was selected here.
There are two methods to implement dynamic scheduled tasks: 1. Implement dynamic scheduled tasks using ScheduledFuture 2
ScheduledFuture Implements dynamic scheduled tasks
1. Create the scheduled task entity class Cron
2. Write services for maintaining scheduled tasks
3. Create a configuration class
@Slf4j @Configuration public class ScheduleConfig { @Autowired private ThreadPoolTaskScheduler threadPoolTaskScheduler; @Autowired ICronService cronService; */ private HashMap<String, ScheduledFuture<? >> scheduleMap = new HashMap<>(); @Bean public ThreadPoolTaskScheduler threadPoolTaskScheduler() { return new ThreadPoolTaskScheduler(); } /** * Initialize the scheduled task */ @bean public void initScheduleTask(){log.info(" Initialize the scheduled task "); /** ** This part involves internal code, not shown, mainly implemented functions: * Call the interface written in part 2 to query all current scheduled tasks List<Cron> * to call the startCron() method, ** * @param crons ** This method is the key to the real dynamic implementation of the start and stop and time cycle, you can call it for your own business, * you modify the dynamic data in the library later call this method, Each Cron object must contain, * execution cycle (cron.getCron()), start-stop status (cron.getCronStatus()), (cron.getCronClass()) */ public void startCron(List< cron > crons){try { For (Cron Cron: crons){ScheduledFuture<? > scheduledFuture = scheduleMap.get(cron.getCronClass()); // if (scheduledFuture! = null){ scheduledFuture.cancel(true); Schedulemap.clear ();}} {schedulemap.clear (); For (Cron Cron: Cron: Cron: Cron: Cron: Crons){// Check whether the current scheduled task is valid. If (cron.getCronStatus().equals(1)) {// Start a new task, The library stores the full class name (package name plus class name) by reflecting it into a Java class and reading the new time ScheduledFuture<? > future = threadPoolTaskScheduler.schedule((Runnable) Class.forName(cron.getCronClass()).newInstance(), new CronTrigger(cron.getCron())); Schedulemap. put(Cron.getCronClass (),future); // If you want to deactivate the schedule map. put(cron.getCronClass(),future); } } } catch (Exception e) { e.printStackTrace(); }}}Copy the code
4. Create the Runnable implementation class to do the real business logic
Public class MyRunnable implements Runnable{@override public void run() {system.out.println (" implements "+ new Date()); }}Copy the code
5. Wrong summaries
2. In the implementation class of Runable, the implementation of the specific business is: query all the data that failed to push, and push again. The query interface is also used here, and is still not injected when Spring beans are injected. In the code is through threadPoolTaskScheduler. The schedule (Runnable task, Trigger the Trigger). Method to enable the scheduled task, by looking at the source code, found that this method is created when the Runable object, is new, so this object is not Spring Bean, so the Runable implementation class does not inject Spring Bean. Solution: Get the Spring container and get the specific Bean from the container. * * * Service Service = SpringContextUtil. GetBean (business interface name. The class);
@Component public class SpringContextUtil implements ApplicationContextAware{ private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (SpringContextUtil.applicationContext == null) { SpringContextUtil.applicationContext = applicationContext; Public static applicationContext getApplicationContext() {return applicationContext; ** @param name * @return */ public static Object getBean(String name) {return getApplicationContext().getBean(name); ** @param clazz * @param <T> * @return */ public static <T> T clazz {return getApplicationContext().getBean(clazz); } public static <T> T;} public static <T> T;} public static <T> T getBean(String name, Class<T> clazz) { return getApplicationContext().getBean(name, clazz); } public static Object createBean(String name, Object object) { DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory(); try { beanFactory.removeBeanDefinition(name); } catch (NoSuchBeanDefinitionException e) { } beanFactory.registerSingleton(name, object); return beanFactory.getBean(name); }}Copy the code