Spring早就提供了分布式锁的实现。原来分布式锁的相关代码存在于Spring Cloud的子项目Spring Cloud Cluster中,后来被迁到Spring Integration中。
Spring Integration为企业集成模式的实现;通俗地说,Spring Integration的定位是一个轻量级的ESB,尽管它做了很多ESB不做的事情。
当前Spring Integration提供的全局锁为以下存储提供了实现:
-
Gemfire
-
JDBC
-
Redis
-
Zookeeper
这些存储都使用相同的API抽象,因此无论使用哪种存储,你的编码过程是相同的,如想更换存储实现不需要更改代码,只需要修改依赖和配置即可。
新建项目结构如下:

-
引入pom依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.11</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>spring_integration</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring_integration</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-integration</artifactId> </dependency> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>RELEASE</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.修改配置文件增加redis配置
server: port: 8081 spring: redis: port: 6379 host: localhost
3.添加配置类
package com.mfc.springintegration.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.integration.redis.util.RedisLockRegistry;
@Configuration
public class RedisLockConfiguration {
@Bean
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
return new RedisLockRegistry(redisConnectionFactory, "svc-redis-lock");
}
}
package com.mfc.springintegration.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
@RestController
@RequestMapping(value = "redisLock")
@Slf4j
public class RedisLockController {
@Autowired
private RedisLockRegistry redisLockRegistry;
@GetMapping("/t1")
public void t1() throws InterruptedException {
Lock lock = redisLockRegistry.obtain("lock");
boolean l1 = lock.tryLock(10, TimeUnit.SECONDS);
log.info("t1-l1 = {}", l1);
TimeUnit.SECONDS.sleep(15);
boolean l2 = lock.tryLock(10, TimeUnit.SECONDS);
log.info("t1-l2 = {}", l2);
lock.unlock();
lock.unlock();
}
@GetMapping("/t2")
public void t2() throws InterruptedException {
Lock lock = redisLockRegistry.obtain("lock");
boolean l1 = lock.tryLock(10, TimeUnit.SECONDS);
log.info("t2-l1 = {}", l1);
TimeUnit.SECONDS.sleep(15);
boolean l2 = lock.tryLock(10, TimeUnit.SECONDS);
log.info("t2-l2 = {}", l2);
lock.unlock();
lock.unlock();
}
}
