Spring Framework integration for ShedLock distributed locking system providing annotation-based task scheduling locks.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
ShedLock Spring Integration provides Spring Framework support for the ShedLock distributed locking library. It enables annotation-based distributed locking for scheduled tasks, ensuring they execute at most once across multiple application nodes. The library offers AOP-based integration with Spring's task scheduling infrastructure.
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-spring</artifactId>
<version>6.6.0</version>
</dependency>shedlock-core and a compatible lock provider implementation<!-- For JDBC/database locking -->
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-jdbc-template</artifactId>
<version>6.6.0</version>
</dependency>
<!-- For Redis locking -->
<dependency>
<groupId>net.javacrumbs.shedlock</groupId>
<artifactId>shedlock-provider-redis-spring</artifactId>
<version>6.6.0</version>
</dependency>Spring-specific annotations and classes:
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import net.javacrumbs.shedlock.spring.annotation.LockProviderToUse;
import net.javacrumbs.shedlock.spring.LockableTaskScheduler;Core ShedLock interfaces and classes:
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.core.LockManager;
import net.javacrumbs.shedlock.core.LockConfiguration;
import net.javacrumbs.shedlock.core.SimpleLock;Common lock provider implementations:
// For JDBC/database locking
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
// For Redis locking
import net.javacrumbs.shedlock.provider.redis.spring.RedisLockProvider;import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import net.javacrumbs.shedlock.core.LockProvider;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Configuration
@EnableSchedulerLock(defaultLockAtMostFor = "10m")
public class SchedulerConfig {
@Bean
public LockProvider lockProvider() {
// Configure your lock provider (e.g., database, Redis)
return new JdbcTemplateLockProvider(dataSource);
}
}
@Component
public class ScheduledTasks {
@Scheduled(cron = "0 */5 * * * *")
@SchedulerLock(name = "scheduledTaskName", lockAtMostFor = "4m", lockAtLeastFor = "1m")
public void scheduledTask() {
// This method will be locked across multiple instances
doWork();
}
}ShedLock Spring Integration is built around several key components:
@EnableSchedulerLock for configuration and @SchedulerLock for method-level lockingCore annotations and configuration classes for enabling and configuring ShedLock in Spring applications.
@EnableSchedulerLock(
interceptMode = InterceptMode.PROXY_METHOD,
defaultLockAtMostFor = "PT30M",
defaultLockAtLeastFor = "PT0S",
mode = AdviceMode.PROXY,
proxyTargetClass = false,
order = Ordered.LOWEST_PRECEDENCE
)
public @interface EnableSchedulerLock {
enum InterceptMode {
PROXY_SCHEDULER, // Deprecated
PROXY_METHOD
}
}Annotations and mechanisms for applying distributed locks directly to scheduled methods.
@SchedulerLock(
name = "lockName",
lockAtMostFor = "PT10M",
lockAtLeastFor = "PT0S"
)
public @interface SchedulerLock {}
@LockProviderToUse("lockProviderBeanName")
public @interface LockProviderToUse {}Classes and utilities for integrating with Spring's TaskScheduler infrastructure.
public class LockableTaskScheduler implements TaskScheduler, DisposableBean {
public LockableTaskScheduler(TaskScheduler taskScheduler, LockManager lockManager);
public ScheduledFuture<?> schedule(Runnable task, Trigger trigger);
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period);
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay);
}Extended configuration extraction and AOP infrastructure for advanced use cases.
public interface ExtendedLockConfigurationExtractor extends LockConfigurationExtractor {
Optional<LockConfiguration> getLockConfiguration(Object object, Method method, Object[] parameterValues);
}
public class SpringLockConfigurationExtractor implements ExtendedLockConfigurationExtractor {
public SpringLockConfigurationExtractor(
Duration defaultLockAtMostFor,
Duration defaultLockAtLeastFor,
StringValueResolver embeddedValueResolver,
Converter<String, Duration> durationConverter,
BeanFactory beanFactory
);
}Essential interfaces and classes from shedlock-core that are used throughout the Spring integration:
public interface LockProvider {
/**
* @return Optional containing SimpleLock if lock was acquired, empty if not acquired
*/
Optional<SimpleLock> lock(LockConfiguration lockConfiguration);
}public interface SimpleLock {
/**
* Unlocks the lock. Once unlocked, no other operations can be called.
*/
void unlock();
/**
* Extends the lock duration. Returns new lock or empty if extension failed.
* Not supported by all providers.
*/
default Optional<SimpleLock> extend(Duration lockAtMostFor, Duration lockAtLeastFor) {
throw new UnsupportedOperationException();
}
}public class LockConfiguration {
public LockConfiguration(Instant createdAt, String name, Duration lockAtMostFor, Duration lockAtLeastFor);
public String getName();
public Instant getLockAtMostUntil();
public Instant getLockAtLeastUntil();
public Instant getUnlockTime();
public Duration getLockAtMostFor();
public Duration getLockAtLeastFor();
}public interface LockManager {
/**
* Executes a callback with an acquired lock.
*/
void executeWithLock(Runnable task, LockConfiguration lockConfiguration);
/**
* Executes a callback with an acquired lock, returning result.
*/
<T> T executeWithLock(Supplier<T> task, LockConfiguration lockConfiguration);
}// Duration formats supported
// ISO8601: "PT30S", "PT10M", "PT1H"
// Simple: "30s", "10m", "1h", "1d"
// Intercept modes
enum InterceptMode {
PROXY_METHOD, // Recommended: Intercepts method calls
PROXY_SCHEDULER // Deprecated: Intercepts scheduler calls
}
// Spring AOP modes
enum AdviceMode {
PROXY, // Standard proxy-based AOP
ASPECTJ // AspectJ weaving
}public class LockingNotSupportedException extends LockException {
// Thrown when locking is not supported (e.g., primitive return types)
}
public class NoUniqueBeanDefinitionException extends BeansException {
// Thrown when multiple LockProviders exist without @LockProviderToUse
}