How to Dynamically Manage Spring Boot Scheduled Tasks with Super‑Scheduled

This article introduces Super‑Scheduled, a Spring Boot starter that enhances native @Scheduled tasks by enabling dynamic runtime management, explains quick integration steps, and details the underlying implementation using configuration components, post‑processors, CGLIB proxies, and a flexible execution chain.

Java High-Performance Architecture
Java High-Performance Architecture
Java High-Performance Architecture
How to Dynamically Manage Spring Boot Scheduled Tasks with Super‑Scheduled

Feature Overview

SpringBoot Super Scheduled is an enhancement tool for Spring Boot's native scheduled tasks, enabling dynamic management while remaining fully compatible with the original @Scheduled annotation without modifying existing tasks.

Quick Start

The functionality is packaged as a Spring Boot starter for plug‑and‑play use.

<dependency>
    <groupId>com.github.guoyixing</groupId>
    <artifactId>spring-boot-starter-super-scheduled</artifactId>
    <version>0.3.1</version>
</dependency>

Source code and usage examples are available at the following repositories:

Gitee: https://gitee.com/qiaodaimadewangcai/super-scheduled GitHub: https://github.com/guoyixing/super-scheduled
Super Scheduled overview diagram
Super Scheduled overview diagram

Implementation Principles

1. Dynamic Management

Configuration management introduces a component SuperScheduledConfig that holds the thread pool, task mappings, and source information.

@Component("superScheduledConfig")
public class SuperScheduledConfig {
    /** Execution thread pool */
    private ThreadPoolTaskScheduler taskScheduler;
    /** Mapping of task name to ScheduledFuture */
    private Map<String, ScheduledFuture> nameToScheduledFuture = new ConcurrentHashMap<>();
    /** Mapping of task name to Runnable */
    private Map<String, Runnable> nameToRunnable = new ConcurrentHashMap<>();
    /** Mapping of task name to source info */
    private Map<String, ScheduledSource> nameToScheduledSource = new ConcurrentHashMap<>();
    // getters and setters omitted for brevity
}

A post‑processor intercepts original scheduled tasks by implementing ApplicationContextAware and BeanPostProcessor, using @DependsOn to ensure SuperScheduledConfig is instantiated first.

@DependsOn({"superScheduledConfig"})
@Component
@Order
public class SuperScheduledPostProcessor implements BeanPostProcessor, ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // obtain configuration, scan methods for @Scheduled, create source, cancel original task, etc.
        return bean;
    }
    // other methods omitted
}
Dynamic management flow diagram
Dynamic management flow diagram

2. ApplicationRunner Initialization

Implements ApplicationRunner to initialize a custom scheduled‑task runner after all beans are created.

@DependsOn("threadPoolTaskScheduler")
@Component
public class SuperScheduledApplicationRunner implements ApplicationRunner, ApplicationContextAware {
    @Autowired
    private SuperScheduledConfig superScheduledConfig;
    @Autowired
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;
    @Override
    public void run(ApplicationArguments args) {
        superScheduledConfig.setTaskScheduler(threadPoolTaskScheduler);
        // retrieve all source data, build execution chain, start tasks, etc.
    }
    // other methods omitted
}
ApplicationRunner initialization diagram
ApplicationRunner initialization diagram

3. Dynamic Management Operations

The SuperScheduledManager class provides methods to modify cron, fixedDelay, fixedRate, query running tasks, cancel or start tasks, and manually trigger execution.

public class SuperScheduledManager {
    public void setScheduledCron(String name, String cron) { /* cancel, create new source, start */ }
    public void setScheduledFixedDelay(String name, Long fixedDelay) { /* similar */ }
    public void setScheduledFixedRate(String name, Long fixedRate) { /* similar */ }
    public List<String> getRunScheduledName() { /* return running task names */ }
    public void cancelScheduled(String name) { /* cancel future */ }
    public void addScheduled(String name, ScheduledSource source) { /* start task */ }
    // other helper methods omitted
}

4. Strengthen Interface

The BaseStrengthen interface defines lifecycle hooks for enhancing scheduled tasks.

public interface BaseStrengthen {
    void before(Object bean, Method method, Object[] args);
    void after(Object bean, Method method, Object[] args);
    void exception(Object bean, Method method, Object[] args);
    void afterFinally(Object bean, Method method, Object[] args);
}

5. Proxy and Execution Chain

CGLIB proxies strengthen implementations into Point nodes, forming a chain executed by SuperScheduledRunnable.

public abstract class Point {
    private String superScheduledName;
    public abstract Object invoke(SuperScheduledRunnable runnable);
}

public class Chain {
    private List<Point> list;
    private int index = -1;
    public int incIndex() { return ++index; }
    public void resetIndex() { index = -1; }
    public List<Point> getList() { return list; }
    public int getIndex() { return index; }
}

public class RunnableBaseInterceptor implements MethodInterceptor {
    private SuperScheduledRunnable runnable;
    private BaseStrengthen strengthen;
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        if ("invoke".equals(method.getName())) {
            strengthen.before(obj, method, args);
            try {
                Object result = runnable.invoke();
                strengthen.after(obj, method, args);
                return result;
            } catch (Exception e) {
                strengthen.exception(obj, method, args);
                throw new SuperScheduledException(strengthen.getClass() + " enhancement error", e);
            } finally {
                strengthen.afterFinally(obj, method, args);
            }
        } else {
            return proxy.invokeSuper(obj, args);
        }
    }
    // constructor omitted
}

public class SuperScheduledRunnable {
    private Method method;
    private Object bean;
    private Chain chain;
    public Object invoke() {
        if (chain.incIndex() == chain.getList().size()) {
            chain.resetIndex();
            return method.invoke(bean);
        } else {
            Point point = chain.getList().get(chain.getIndex());
            return point.invoke(this);
        }
    }
    // getters and setters omitted
}

Conclusion

By combining configuration management, post‑processing, CGLIB proxying, and a flexible execution chain, Super‑Scheduled provides a powerful way to control, modify, and monitor Spring Boot scheduled tasks at runtime without altering the original code.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

cglibScheduled Tasksspring-bootDynamic Management
Java High-Performance Architecture
Written by

Java High-Performance Architecture

Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.