Compare commits
6 Commits
release_1.
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ef657d0ba | ||
|
|
0f9ce0441e | ||
|
|
bc1fd8fc71 | ||
|
|
4ce823e161 | ||
|
|
62d2a60edc | ||
|
|
0bae77fc8a |
14
CHANGELOG.md
14
CHANGELOG.md
@@ -45,3 +45,17 @@
|
||||
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
||||
|:---|:---|:---|:---|:--|
|
||||
| 1 | A | 整合 spring | 2022-12-7 14:45:40 | |
|
||||
|
||||
# release_1.2.0
|
||||
|
||||
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
||||
|:---|:---|:---|:---|:--|
|
||||
| 1 | A | 添加 keyFormat | 2022-12-8 14:45:40 | |
|
||||
| 2 | A | 添加锁释放失败 | 2022-12-8 14:45:40 | |
|
||||
| 3 | O | 加锁处理优化,接口统一优化 | 2022-12-8 14:45:40 | |
|
||||
|
||||
# release_1.3.0
|
||||
|
||||
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
||||
|:---|:---|:---|:---|:--|
|
||||
| 1 | A | 让 redis-config 主动启用,避免无法主动管理的情况 | 2022-12-8 14:45:40 | |
|
||||
|
||||
145
README.md
145
README.md
@@ -1,23 +1,27 @@
|
||||
# 项目简介
|
||||
|
||||
为 java 设计的锁。
|
||||
[lock](https://github.com/houbb/lock) 为 java 设计的分布式锁,开箱即用,纵享丝滑。
|
||||
|
||||
[](http://mvnrepository.com/artifact/com.github.houbb/lock)
|
||||
[](https://www.travis-ci.org/houbb/lock?branch=master)
|
||||
[](https://coveralls.io/github/houbb/lock?branch=master)
|
||||
|
||||
开源地址:[https://github.com/houbb/lock](https://github.com/houbb/lock)
|
||||
|
||||
## 目的
|
||||
|
||||
- 开箱即用,支持注解式和过程式调用
|
||||
|
||||
- 基于 redis 的分布式锁
|
||||
|
||||
- 内置支持多种 redis 的整合方式
|
||||
|
||||
- 渐进式设计,可独立于 spring 使用
|
||||
|
||||
- 整合 spring
|
||||
|
||||
- 整合 spring-boot
|
||||
|
||||
- 开箱即用,支持注解。
|
||||
|
||||
- 支持多种 redis 的声明方式
|
||||
|
||||
# 变更日志
|
||||
|
||||
> [变更日志](CHANGELOG.md)
|
||||
@@ -36,7 +40,7 @@ maven 3.x+
|
||||
<dependency>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<artifactId>lock-core</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.3.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
@@ -45,9 +49,8 @@ maven 3.x+
|
||||
基于本地 redis 的测试案例。
|
||||
|
||||
```java
|
||||
ILock lock = LockBs.newInstance()
|
||||
.init();
|
||||
|
||||
public void helloTest() {
|
||||
ILock lock = LockBs.newInstance();
|
||||
String key = "ddd";
|
||||
try {
|
||||
// 加锁
|
||||
@@ -59,6 +62,21 @@ try {
|
||||
// 释放锁
|
||||
lock.unlock(key);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 配置化
|
||||
|
||||
为了便于拓展,LockBs 的配置支持自定义:
|
||||
|
||||
```java
|
||||
LockBs.newInstance()
|
||||
.id(Ids.uuid32()) //id 生成策略
|
||||
.cache(JedisRedisServiceFactory.pooled("127.0.0.1", 6379)) //缓存策略
|
||||
.lockSupport(new RedisLockSupport()) // 锁实现策略
|
||||
.lockKeyFormat(new LockKeyFormat()) // 针对 key 的格式化处理策略
|
||||
.lockReleaseFailHandler(new LockReleaseFailHandler()) //释放锁失败处理
|
||||
;
|
||||
```
|
||||
|
||||
# 整合 spring
|
||||
@@ -69,7 +87,7 @@ try {
|
||||
<dependency>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<artifactId>lock-spring</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.3.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
@@ -79,17 +97,65 @@ try {
|
||||
|
||||
`@EnableLock` 启用分布式锁。
|
||||
|
||||
`@EnableRedisConfig` 启用 redis 的默认配置。
|
||||
|
||||
```xml
|
||||
@Configurable
|
||||
@ComponentScan(basePackages = "com.github.houbb.lock.test.service")
|
||||
@EnableLock
|
||||
@EnableRedisConfig
|
||||
public class SpringConfig {
|
||||
}
|
||||
```
|
||||
|
||||
`EnableLock` 注解说明,和引导类对应:
|
||||
|
||||
```java
|
||||
public @interface EnableLock {
|
||||
|
||||
/**
|
||||
* 唯一标识生成策略
|
||||
* @return 结果
|
||||
*/
|
||||
String id() default "lockId";
|
||||
|
||||
/**
|
||||
* 缓存实现策略 bean 名称
|
||||
*
|
||||
* 默认引入 redis-config 中的配置
|
||||
*
|
||||
* @return 实现
|
||||
*/
|
||||
String cache() default "springRedisService";
|
||||
|
||||
/**
|
||||
* 加锁 key 格式化策略
|
||||
* @return 策略
|
||||
*/
|
||||
String lockKeyFormat() default "lockKeyFormat";
|
||||
|
||||
/**
|
||||
* 锁释放失败处理类
|
||||
* @return 结果
|
||||
*/
|
||||
String lockReleaseFailHandler() default "lockReleaseFailHandler";
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
其中 `springRedisService` 使用的是 [redis-config](https://github.com/houbb/redis-config) 中的实现。
|
||||
|
||||
对应注解 `@EnableRedisConfig`,redis 的配置信息如下:
|
||||
|
||||
| 配置 | 说明 | 默认值
|
||||
|:---|:---|:----|
|
||||
| redis.address | redis 地址 | 127.0.0.1 |
|
||||
| redis.port | redis 端口 | 6379 |
|
||||
| redis.password | redis 密码 | |
|
||||
|
||||
### 使用 LockBs
|
||||
|
||||
我们可以直接 `LockBs` 的引导类。
|
||||
我们可以直接 `LockBs` 的引导类,这种适合一些更加灵活的场景。
|
||||
|
||||
```java
|
||||
@ContextConfiguration(classes = SpringConfig.class)
|
||||
@@ -124,7 +190,7 @@ public class SpringServiceRawTest {
|
||||
|
||||
当然,我们可以在方法上直接指定注解 `@Lock`,使用更加方便。
|
||||
|
||||
支持 SPEL 表达式。
|
||||
直接使用,AOP 切面生效即可。
|
||||
|
||||
```java
|
||||
@Service
|
||||
@@ -140,7 +206,39 @@ public class UserService {
|
||||
}
|
||||
```
|
||||
|
||||
直接使用,AOP 切面生效即可。
|
||||
`@Lock` 属性说明,value 用于指定 key,支持 SPEL 表达式。
|
||||
|
||||
其他属性,和引导类的方法参数一一对应。
|
||||
|
||||
```java
|
||||
public @interface Lock {
|
||||
|
||||
/**
|
||||
* 缓存的 key 策略,支持 SpEL
|
||||
* @return 结果
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* 时间单位
|
||||
* @return 单位
|
||||
*/
|
||||
TimeUnit timeUnit() default TimeUnit.SECONDS;
|
||||
|
||||
/**
|
||||
* 等待锁时间
|
||||
* @return 等待锁时间
|
||||
*/
|
||||
long waitLockTime() default 10;
|
||||
|
||||
/**
|
||||
* 业务加锁时间
|
||||
* @return 加锁时间
|
||||
*/
|
||||
long lockTime() default 60;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
# spring boot 整合
|
||||
|
||||
@@ -150,7 +248,7 @@ public class UserService {
|
||||
<dependency>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<artifactId>lock-springboot-starter</artifactId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.3.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
@@ -166,3 +264,22 @@ public class UserService {
|
||||
|
||||
- [x] 分布式锁注解支持
|
||||
|
||||
# 拓展阅读
|
||||
|
||||
[Redis 分布式锁](https://houbb.github.io/2018/09/08/redis-learn-42-distributed-lock-redis)
|
||||
|
||||
[java 从零实现 redis 分布式锁](https://houbb.github.io/2018/09/08/redis-learn-43-distributed-lock-redis-java-impl)
|
||||
|
||||
# 缓存相关工具
|
||||
|
||||
[cache: 手写渐进式 redis](https://github.com/houbb/cache)
|
||||
|
||||
[common-cache: 通用缓存标准定义](https://github.com/houbb/common-cache)
|
||||
|
||||
[redis-config: 兼容各种常见的 redis 配置模式](https://github.com/houbb/redis-config)
|
||||
|
||||
[lock: 开箱即用的分布式锁](https://github.com/houbb/lock)
|
||||
|
||||
[resubmit: 防重复提交](https://github.com/houbb/resubmit)
|
||||
|
||||
[rate-limit: 限流](https://github.com/houbb/rate-limit/)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>lock</artifactId>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -12,13 +12,33 @@ public interface ILock {
|
||||
/**
|
||||
* 尝试加锁,如果失败,会一直尝试。
|
||||
*
|
||||
* @param time 时间
|
||||
* @param unit 当为
|
||||
* @param key key
|
||||
* @param timeUnit 时间单位
|
||||
* @param waitLockTime 等待锁时间
|
||||
* @param lockTime 加锁时间
|
||||
* @return 返回
|
||||
* @since 0.0.1
|
||||
*/
|
||||
boolean tryLock(long time, TimeUnit unit, String key);
|
||||
boolean tryLock(String key, TimeUnit timeUnit, long lockTime, long waitLockTime);
|
||||
|
||||
/**
|
||||
* 尝试加锁,只加锁一次
|
||||
* @param key key
|
||||
* @param timeUnit 时间单位
|
||||
* @param lockTime 加锁时间
|
||||
* @return 返回
|
||||
* @since 0.0.1
|
||||
*/
|
||||
boolean tryLock(String key, TimeUnit timeUnit, long lockTime);
|
||||
|
||||
/**
|
||||
* 尝试加锁,只加锁一次
|
||||
* @param key key
|
||||
* @param lockTime 加锁时间
|
||||
* @return 返回
|
||||
* @since 0.0.1
|
||||
*/
|
||||
boolean tryLock(String key, long lockTime);
|
||||
|
||||
/**
|
||||
* 尝试加锁,只加锁一次
|
||||
@@ -32,6 +52,7 @@ public interface ILock {
|
||||
* 解锁
|
||||
* @param key key
|
||||
* @since 0.0.1
|
||||
* @return 是否释放锁成功
|
||||
*/
|
||||
boolean unlock(String key);
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.github.houbb.lock.api.core;
|
||||
|
||||
/**
|
||||
* 分布式锁 KEY 格式化处理
|
||||
*
|
||||
* @author binbin.hou
|
||||
* @since 0.0.1
|
||||
*/
|
||||
public interface ILockKeyFormat {
|
||||
|
||||
/**
|
||||
* 对 key 进行格式化处理,避免缓存命名空间处理等问题
|
||||
*
|
||||
* @param formatContext 上下文
|
||||
* @return 返回
|
||||
* @since 1.2.0
|
||||
*/
|
||||
String format(ILockKeyFormatContext formatContext);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.github.houbb.lock.api.core;
|
||||
|
||||
/**
|
||||
* 分布式锁 KEY 格式化处理上下文
|
||||
*
|
||||
* @author binbin.hou
|
||||
* @since 0.0.1
|
||||
*/
|
||||
public interface ILockKeyFormatContext {
|
||||
|
||||
/**
|
||||
* 原始的 key
|
||||
*
|
||||
* @return 返回
|
||||
* @since 1.2.0
|
||||
*/
|
||||
String rawKey();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.github.houbb.lock.api.core;
|
||||
|
||||
/**
|
||||
* 释放锁失败处理类
|
||||
*
|
||||
* @author binbin.hou
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public interface ILockReleaseFailHandler {
|
||||
|
||||
/**
|
||||
* 处理
|
||||
* @param context 上下文
|
||||
* @since 1.2.0
|
||||
*/
|
||||
void handle(ILockReleaseFailHandlerContext context);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.github.houbb.lock.api.core;
|
||||
|
||||
/**
|
||||
* 释放锁失败处理类
|
||||
*
|
||||
* @author binbin.hou
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public interface ILockReleaseFailHandlerContext {
|
||||
|
||||
/**
|
||||
* 释放锁对应的 key
|
||||
* @return 结果
|
||||
* @since 1.2.0
|
||||
*/
|
||||
String key();
|
||||
|
||||
}
|
||||
@@ -12,30 +12,21 @@ public interface ILockSupport {
|
||||
/**
|
||||
* 尝试加锁,如果失败,会一直尝试。
|
||||
*
|
||||
* @param time 时间
|
||||
* @param unit 单位
|
||||
* @param key key
|
||||
* 1. 如果等待时间小于等于0,则直接执行加锁
|
||||
* 2. 如果等待时间大于等于0,则尝试循环等待。
|
||||
*
|
||||
* @param context 上下文
|
||||
* @return 返回
|
||||
* @since 0.0.1
|
||||
*/
|
||||
boolean tryLock(long time, TimeUnit unit, String key, final ILockSupportContext context);
|
||||
|
||||
/**
|
||||
* 尝试加锁,只加锁一次
|
||||
* @param key key
|
||||
* @param context 上下文
|
||||
* @return 返回
|
||||
* @since 0.0.1
|
||||
*/
|
||||
boolean tryLock(String key, final ILockSupportContext context);
|
||||
boolean tryLock(final ILockSupportContext context);
|
||||
|
||||
/**
|
||||
* 解锁
|
||||
* @param key key
|
||||
* @param context 上下文
|
||||
* @since 0.0.1
|
||||
* @return 结果
|
||||
*/
|
||||
boolean unlock(String key, final ILockSupportContext context);
|
||||
boolean unlock(final ILockSupportContext context);
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.github.houbb.lock.api.core;
|
||||
import com.github.houbb.common.cache.api.service.ICommonCacheService;
|
||||
import com.github.houbb.id.api.Id;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 分布式锁接口定义
|
||||
* @author binbin.hou
|
||||
@@ -11,21 +13,60 @@ import com.github.houbb.id.api.Id;
|
||||
public interface ILockSupportContext {
|
||||
|
||||
/**
|
||||
* 标识
|
||||
*
|
||||
* @return 标识策略
|
||||
* @since 0.0.4
|
||||
*/
|
||||
Id id();
|
||||
|
||||
/**
|
||||
* 缓存
|
||||
* @return 缓存策略
|
||||
* @since 0.0.4
|
||||
*/
|
||||
ICommonCacheService cache();
|
||||
|
||||
/**
|
||||
* 锁的过期时间
|
||||
* @return 结果
|
||||
* 时间单位
|
||||
* @return 时间单位
|
||||
*/
|
||||
int lockExpireMills();
|
||||
TimeUnit timeUnit();
|
||||
|
||||
/**
|
||||
* 加锁时间
|
||||
* @return 时间
|
||||
* @since 1.2.0
|
||||
*/
|
||||
long lockTime();
|
||||
|
||||
/**
|
||||
* 等待加锁时间
|
||||
* @return 等待时间
|
||||
* @since 1.2.0
|
||||
*/
|
||||
long waitLockTime();
|
||||
|
||||
/**
|
||||
* 缓存对应的 key
|
||||
* @return 结果
|
||||
* @since 1.2.0
|
||||
*/
|
||||
String key();
|
||||
|
||||
/**
|
||||
* 锁 key 格式化
|
||||
* @since 1.2.0
|
||||
* @return 格式化
|
||||
*/
|
||||
ILockKeyFormat lockKeyFormat();
|
||||
|
||||
/**
|
||||
* 锁释放失败处理类
|
||||
* @since 1.2.0
|
||||
* @return 失败处理
|
||||
*/
|
||||
ILockReleaseFailHandler lockReleaseFailHandler();
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>lock</artifactId>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -4,10 +4,9 @@ import com.github.houbb.common.cache.api.service.ICommonCacheService;
|
||||
import com.github.houbb.heaven.util.common.ArgUtil;
|
||||
import com.github.houbb.id.api.Id;
|
||||
import com.github.houbb.id.core.core.Ids;
|
||||
import com.github.houbb.lock.api.core.ILock;
|
||||
import com.github.houbb.lock.api.core.ILockSupport;
|
||||
import com.github.houbb.lock.api.core.ILockSupportContext;
|
||||
import com.github.houbb.lock.core.constant.LockConst;
|
||||
import com.github.houbb.lock.api.core.*;
|
||||
import com.github.houbb.lock.core.support.format.LockKeyFormat;
|
||||
import com.github.houbb.lock.core.support.handler.LockReleaseFailHandler;
|
||||
import com.github.houbb.lock.core.support.lock.LockSupportContext;
|
||||
import com.github.houbb.lock.core.support.lock.RedisLockSupport;
|
||||
import com.github.houbb.redis.config.core.factory.JedisRedisServiceFactory;
|
||||
@@ -22,46 +21,47 @@ import java.util.concurrent.TimeUnit;
|
||||
*/
|
||||
public final class LockBs implements ILock {
|
||||
|
||||
private LockBs(){}
|
||||
private LockBs() {
|
||||
}
|
||||
|
||||
public static LockBs newInstance() {
|
||||
return new LockBs();
|
||||
}
|
||||
|
||||
/**
|
||||
* 加锁锁定时间
|
||||
* @since 0.0.4
|
||||
*/
|
||||
private int lockExpireMills = LockConst.DEFAULT_EXPIRE_MILLS;
|
||||
|
||||
/**
|
||||
* 标识策略
|
||||
*
|
||||
* @since 0.0.4
|
||||
*/
|
||||
private Id id = Ids.uuid32();
|
||||
|
||||
/**
|
||||
* 缓存策略
|
||||
*
|
||||
* @since 0.0.4
|
||||
*/
|
||||
private ICommonCacheService cache = JedisRedisServiceFactory.pooled("127.0.0.1", 6379);
|
||||
|
||||
/**
|
||||
* 锁支持策略
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private ILockSupport lockSupport = new RedisLockSupport();
|
||||
|
||||
/**
|
||||
* 锁上下文
|
||||
* @since 1.0.0
|
||||
* 锁 key 格式化
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private ILockSupportContext lockSupportContext = null;
|
||||
private ILockKeyFormat lockKeyFormat = new LockKeyFormat();
|
||||
|
||||
public LockBs lockExpireMills(int lockExpireMills) {
|
||||
this.lockExpireMills = lockExpireMills;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* 锁释放失败处理类
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private ILockReleaseFailHandler lockReleaseFailHandler = new LockReleaseFailHandler();
|
||||
|
||||
public LockBs id(Id id) {
|
||||
ArgUtil.notNull(id, "id");
|
||||
@@ -84,48 +84,67 @@ public final class LockBs implements ILock{
|
||||
return this;
|
||||
}
|
||||
|
||||
public LockBs lockKeyFormat(ILockKeyFormat lockKeyFormat) {
|
||||
ArgUtil.notNull(lockKeyFormat, "lockKeyFormat");
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
public LockBs init() {
|
||||
this.lockSupportContext = LockSupportContext.newInstance()
|
||||
.id(id)
|
||||
.cache(cache)
|
||||
.lockExpireMills(lockExpireMills);
|
||||
|
||||
this.lockKeyFormat = lockKeyFormat;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LockBs lockReleaseFailHandler(ILockReleaseFailHandler lockReleaseFailHandler) {
|
||||
ArgUtil.notNull(lockReleaseFailHandler, "lockReleaseFailHandler");
|
||||
|
||||
this.lockReleaseFailHandler = lockReleaseFailHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ILockReleaseFailHandler lockReleaseFailHandler() {
|
||||
return lockReleaseFailHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryLock(long time, TimeUnit unit, String key) {
|
||||
ArgUtil.notEmpty(key, "key");
|
||||
this.checkInitStatus();
|
||||
public boolean tryLock(String key, TimeUnit timeUnit, long lockTime, long waitLockTime) {
|
||||
ILockSupportContext supportContext = buildLockSupportContext(key, timeUnit, lockTime, waitLockTime);
|
||||
return this.lockSupport.tryLock(supportContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryLock(String key, TimeUnit timeUnit, long lockTime) {
|
||||
return this.tryLock(key, timeUnit, lockTime, 0);
|
||||
}
|
||||
|
||||
return this.lockSupport.tryLock(time, unit, key, lockSupportContext);
|
||||
@Override
|
||||
public boolean tryLock(String key, long lockTime) {
|
||||
return this.tryLock(key, TimeUnit.SECONDS, lockTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryLock(String key) {
|
||||
ArgUtil.notEmpty(key, "key");
|
||||
this.checkInitStatus();
|
||||
|
||||
return this.lockSupport.tryLock(key, lockSupportContext);
|
||||
return this.tryLock(key, 60);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unlock(String key) {
|
||||
ILockSupportContext supportContext = buildLockSupportContext(key, TimeUnit.SECONDS, 0, 0);
|
||||
return this.lockSupport.unlock(supportContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建上下文
|
||||
*
|
||||
* @param key key
|
||||
* @param timeUnit 时间
|
||||
* @param lockTime 加锁时间
|
||||
* @param waitLockTime 等待加锁时间
|
||||
* @return 结果
|
||||
* @since 1.0.0
|
||||
*/
|
||||
private ILockSupportContext buildLockSupportContext(String key, TimeUnit timeUnit, long lockTime, long waitLockTime) {
|
||||
ArgUtil.notEmpty(key, "key");
|
||||
this.checkInitStatus();
|
||||
ArgUtil.notNull(timeUnit, "timeUnit");
|
||||
|
||||
return this.lockSupport.unlock(key, lockSupportContext);
|
||||
ILockSupportContext context = LockSupportContext.newInstance().id(id).cache(cache).lockKeyFormat(lockKeyFormat).lockReleaseFailHandler(lockReleaseFailHandler).key(key).timeUnit(timeUnit).lockTime(lockTime).waitLockTime(waitLockTime);
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
private void checkInitStatus() {
|
||||
ArgUtil.notNull(lockSupportContext, "please init() first!");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.github.houbb.lock.core.support.format;
|
||||
|
||||
import com.github.houbb.lock.api.core.ILockKeyFormat;
|
||||
import com.github.houbb.lock.api.core.ILockKeyFormatContext;
|
||||
|
||||
/**
|
||||
* 简单的格式化处理
|
||||
* @since 1.2.0
|
||||
* @author dh
|
||||
*/
|
||||
public class LockKeyFormat implements ILockKeyFormat {
|
||||
|
||||
@Override
|
||||
public String format(ILockKeyFormatContext formatContext) {
|
||||
String rawKey = formatContext.rawKey();
|
||||
|
||||
String format = "DISTRIBUTED-LOCK:%s";
|
||||
return String.format(format, rawKey);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.github.houbb.lock.core.support.format;
|
||||
|
||||
import com.github.houbb.lock.api.core.ILockKeyFormatContext;
|
||||
|
||||
/**
|
||||
* 上下文
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class LockKeyFormatContext implements ILockKeyFormatContext {
|
||||
|
||||
|
||||
/**
|
||||
* 原始的 key
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private String rawKey;
|
||||
|
||||
public static LockKeyFormatContext newInstance() {
|
||||
return new LockKeyFormatContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String rawKey() {
|
||||
return rawKey;
|
||||
}
|
||||
|
||||
public LockKeyFormatContext rawKey(String rawKey) {
|
||||
this.rawKey = rawKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.github.houbb.lock.core.support.handler;
|
||||
|
||||
import com.github.houbb.lock.api.core.ILockReleaseFailHandler;
|
||||
import com.github.houbb.lock.api.core.ILockReleaseFailHandlerContext;
|
||||
import com.github.houbb.log.integration.core.Log;
|
||||
import com.github.houbb.log.integration.core.LogFactory;
|
||||
|
||||
/**
|
||||
* 释放锁失败处理类
|
||||
*
|
||||
* @author binbin.hou
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class LockReleaseFailHandler implements ILockReleaseFailHandler {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(LockReleaseFailHandler.class);
|
||||
|
||||
@Override
|
||||
public void handle(ILockReleaseFailHandlerContext context) {
|
||||
LOG.error("[LOCK] release lock failed {}", context.key());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.github.houbb.lock.core.support.handler;
|
||||
|
||||
import com.github.houbb.lock.api.core.ILockReleaseFailHandlerContext;
|
||||
|
||||
/**
|
||||
* 锁释放失败上下文
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public class LockReleaseFailHandlerContext implements ILockReleaseFailHandlerContext {
|
||||
|
||||
/**
|
||||
* 释放锁对应的 key
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private String key;
|
||||
|
||||
public static LockReleaseFailHandlerContext newInstance() {
|
||||
return new LockReleaseFailHandlerContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public LockReleaseFailHandlerContext key(String key) {
|
||||
this.key = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,7 +2,13 @@ package com.github.houbb.lock.core.support.lock;
|
||||
|
||||
import com.github.houbb.common.cache.api.service.ICommonCacheService;
|
||||
import com.github.houbb.id.api.Id;
|
||||
import com.github.houbb.lock.api.core.ILockKeyFormat;
|
||||
import com.github.houbb.lock.api.core.ILockReleaseFailHandler;
|
||||
import com.github.houbb.lock.api.core.ILockSupportContext;
|
||||
import com.github.houbb.lock.core.support.format.LockKeyFormat;
|
||||
import com.github.houbb.lock.core.support.handler.LockReleaseFailHandler;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 分布式锁接口定义
|
||||
@@ -25,13 +31,43 @@ public class LockSupportContext implements ILockSupportContext {
|
||||
* 缓存策略
|
||||
* @since 0.0.4
|
||||
*/
|
||||
private ICommonCacheService commonCacheService;
|
||||
private ICommonCacheService cache;
|
||||
|
||||
/**
|
||||
* 锁的过期时间
|
||||
* @since 1.0.0
|
||||
* 时间单位
|
||||
*/
|
||||
private int lockExpireMills;
|
||||
private TimeUnit timeUnit;
|
||||
|
||||
/**
|
||||
* 加锁时间
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private long lockTime;
|
||||
|
||||
/**
|
||||
* 等待加锁时间
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private long waitLockTime;
|
||||
|
||||
/**
|
||||
* 缓存对应的 key
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 锁 key 格式化
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private ILockKeyFormat lockKeyFormat;
|
||||
|
||||
/**
|
||||
* 锁释放失败处理类
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private ILockReleaseFailHandler lockReleaseFailHandler;
|
||||
|
||||
|
||||
@Override
|
||||
public Id id() {
|
||||
@@ -45,21 +81,72 @@ public class LockSupportContext implements ILockSupportContext {
|
||||
|
||||
@Override
|
||||
public ICommonCacheService cache() {
|
||||
return commonCacheService;
|
||||
return cache;
|
||||
}
|
||||
|
||||
public LockSupportContext cache(ICommonCacheService commonCacheService) {
|
||||
this.commonCacheService = commonCacheService;
|
||||
public LockSupportContext cache(ICommonCacheService cache) {
|
||||
this.cache = cache;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lockExpireMills() {
|
||||
return lockExpireMills;
|
||||
public TimeUnit timeUnit() {
|
||||
return timeUnit;
|
||||
}
|
||||
|
||||
public LockSupportContext lockExpireMills(int lockExpireMills) {
|
||||
this.lockExpireMills = lockExpireMills;
|
||||
public LockSupportContext timeUnit(TimeUnit timeUnit) {
|
||||
this.timeUnit = timeUnit;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long lockTime() {
|
||||
return lockTime;
|
||||
}
|
||||
|
||||
public LockSupportContext lockTime(long lockTime) {
|
||||
this.lockTime = lockTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long waitLockTime() {
|
||||
return waitLockTime;
|
||||
}
|
||||
|
||||
public LockSupportContext waitLockTime(long waitLockTime) {
|
||||
this.waitLockTime = waitLockTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public LockSupportContext key(String key) {
|
||||
this.key = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILockKeyFormat lockKeyFormat() {
|
||||
return lockKeyFormat;
|
||||
}
|
||||
|
||||
public LockSupportContext lockKeyFormat(ILockKeyFormat lockKeyFormat) {
|
||||
this.lockKeyFormat = lockKeyFormat;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILockReleaseFailHandler lockReleaseFailHandler() {
|
||||
return lockReleaseFailHandler;
|
||||
}
|
||||
|
||||
public LockSupportContext lockReleaseFailHandler(ILockReleaseFailHandler lockReleaseFailHandler) {
|
||||
this.lockReleaseFailHandler = lockReleaseFailHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.github.houbb.lock.core.support.lock;
|
||||
|
||||
import com.github.houbb.common.cache.api.service.ICommonCacheService;
|
||||
import com.github.houbb.heaven.util.lang.StringUtil;
|
||||
import com.github.houbb.id.api.Id;
|
||||
import com.github.houbb.id.core.util.IdThreadLocalHelper;
|
||||
import com.github.houbb.lock.api.core.ILockKeyFormat;
|
||||
import com.github.houbb.lock.api.core.ILockSupport;
|
||||
import com.github.houbb.lock.api.core.ILockSupportContext;
|
||||
import com.github.houbb.lock.core.support.format.LockKeyFormatContext;
|
||||
import com.github.houbb.log.integration.core.Log;
|
||||
import com.github.houbb.log.integration.core.LogFactory;
|
||||
import com.github.houbb.redis.config.core.constant.JedisConst;
|
||||
@@ -22,25 +25,27 @@ public class RedisLockSupport implements ILockSupport {
|
||||
private final Log log = LogFactory.getLog(RedisLockSupport.class);
|
||||
|
||||
@Override
|
||||
public boolean tryLock(long time, TimeUnit unit, String key, ILockSupportContext context) {
|
||||
public boolean tryLock(ILockSupportContext context) {
|
||||
long startTimeMills = System.currentTimeMillis();
|
||||
|
||||
// 一次获取,直接成功
|
||||
boolean result = this.tryLock(key, context);
|
||||
boolean result = this.doLock(context);
|
||||
if(result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 时间判断
|
||||
if(time <= 0) {
|
||||
final TimeUnit timeUnit = context.timeUnit();
|
||||
final long waitLockTime = context.waitLockTime();
|
||||
if(waitLockTime <= 0) {
|
||||
return false;
|
||||
}
|
||||
long durationMills = unit.toMillis(time);
|
||||
long durationMills = timeUnit.toMillis(waitLockTime);
|
||||
long endMills = startTimeMills + durationMills;
|
||||
|
||||
// 循环等待
|
||||
while (System.currentTimeMillis() < endMills) {
|
||||
result = tryLock(key, context);
|
||||
result = this.doLock(context);
|
||||
if(result) {
|
||||
return true;
|
||||
}
|
||||
@@ -49,33 +54,48 @@ public class RedisLockSupport implements ILockSupport {
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
log.debug("[LOCK] try lock wait 1 mills.");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryLock(String key, ILockSupportContext context) {
|
||||
/**
|
||||
* 执行加锁
|
||||
* @param context 上下文
|
||||
* @return 结果
|
||||
*/
|
||||
protected boolean doLock(ILockSupportContext context) {
|
||||
final String key = this.getActualKey(context);
|
||||
|
||||
// 生成当前线程的唯一标识
|
||||
Id id = context.id();
|
||||
final Id id = context.id();
|
||||
final String requestId = id.id();
|
||||
IdThreadLocalHelper.put(requestId);
|
||||
log.info("[LOCK] BEGIN TRY LOCK key: {} requestId: {}", key, requestId);
|
||||
|
||||
final ICommonCacheService commonCacheService = context.cache();
|
||||
final int lockExpireMills = context.lockExpireMills();
|
||||
final TimeUnit timeUnit = context.timeUnit();
|
||||
final long lockTime = context.lockTime();
|
||||
final int lockExpireMills = (int) timeUnit.toMillis(lockTime);
|
||||
|
||||
String result = commonCacheService.set(key, requestId, JedisConst.SET_IF_NOT_EXIST, JedisConst.SET_WITH_EXPIRE_TIME, lockExpireMills);
|
||||
log.info("[LOCK] END TRY LOCK key: {}, requestId: {}, result: {}", key, requestId, result);
|
||||
log.info("[LOCK] END TRY LOCK key: {}, requestId: {}, lockExpireMills: {}, result: {}", key, requestId, lockExpireMills, result);
|
||||
return JedisConst.OK.equalsIgnoreCase(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unlock(String key, ILockSupportContext context) {
|
||||
public boolean unlock(ILockSupportContext context) {
|
||||
final String key = this.getActualKey(context);
|
||||
|
||||
String requestId = IdThreadLocalHelper.get();
|
||||
log.info("[LOCK] BEGIN UN LOCK key: {} requestId: {}", key, requestId);
|
||||
|
||||
if(StringUtil.isEmpty(requestId)) {
|
||||
log.warn("[LOCK] UNLOCK requestId not found, ignore");
|
||||
return false;
|
||||
}
|
||||
|
||||
final ICommonCacheService commonCacheService = context.cache();
|
||||
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
|
||||
Object result = commonCacheService.eval(script, Collections.singletonList(key), Collections.singletonList(requestId));
|
||||
@@ -83,4 +103,21 @@ public class RedisLockSupport implements ILockSupport {
|
||||
return JedisConst.RELEASE_SUCCESS.equals(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建真正的 key
|
||||
* @param context 上下文
|
||||
* @return 结果
|
||||
* @since 1.2.0
|
||||
*/
|
||||
private String getActualKey(ILockSupportContext context) {
|
||||
final String rawKey = context.key();
|
||||
final ILockKeyFormat keyFormat = context.lockKeyFormat();
|
||||
LockKeyFormatContext formatContext = LockKeyFormatContext.newInstance()
|
||||
.rawKey(rawKey);
|
||||
|
||||
String key = keyFormat.format(formatContext);
|
||||
log.info("[LOCK] format rawKey: {} to key: {}", rawKey, key);
|
||||
return key;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>lock</artifactId>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -18,13 +18,6 @@ import java.lang.annotation.*;
|
||||
@EnableAspectJAutoProxy
|
||||
public @interface EnableLock {
|
||||
|
||||
/**
|
||||
* 加锁过期时间
|
||||
* @return 时间
|
||||
* @since 1.1.0
|
||||
*/
|
||||
int lockExpireMills() default 60 * 1000;
|
||||
|
||||
/**
|
||||
* 唯一标识生成策略
|
||||
* @return 结果
|
||||
@@ -42,5 +35,18 @@ public @interface EnableLock {
|
||||
*/
|
||||
String cache() default "springRedisService";
|
||||
|
||||
/**
|
||||
* 加锁 key 格式化策略
|
||||
* @return 策略
|
||||
* @since 1.2.0
|
||||
*/
|
||||
String lockKeyFormat() default "lockKeyFormat";
|
||||
|
||||
/**
|
||||
* 锁释放失败处理类
|
||||
* @return 结果
|
||||
* @since 1.2.0
|
||||
*/
|
||||
String lockReleaseFailHandler() default "lockReleaseFailHandler";
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.github.houbb.lock.spring.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 分布式加锁注解
|
||||
@@ -20,9 +21,24 @@ public @interface Lock {
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* 尝试获取锁等待时间
|
||||
* @return 结果
|
||||
* 时间单位
|
||||
* @return 单位
|
||||
* @since 1.2.0
|
||||
*/
|
||||
long tryLockMills() default 10 * 1000;
|
||||
TimeUnit timeUnit() default TimeUnit.SECONDS;
|
||||
|
||||
/**
|
||||
* 等待锁时间
|
||||
* @return 等待锁时间
|
||||
* @since 1.2.0
|
||||
*/
|
||||
long waitLockTime() default 10;
|
||||
|
||||
/**
|
||||
* 业务加锁时间
|
||||
* @return 加锁时间
|
||||
* @since 1.2.0
|
||||
*/
|
||||
long lockTime() default 60;
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.github.houbb.heaven.util.lang.StringUtil;
|
||||
import com.github.houbb.heaven.util.util.ArrayUtil;
|
||||
import com.github.houbb.lock.api.exception.LockException;
|
||||
import com.github.houbb.lock.core.bs.LockBs;
|
||||
import com.github.houbb.lock.core.support.handler.LockReleaseFailHandlerContext;
|
||||
import com.github.houbb.lock.spring.annotation.Lock;
|
||||
import com.github.houbb.log.integration.core.Log;
|
||||
import com.github.houbb.log.integration.core.LogFactory;
|
||||
@@ -24,9 +25,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author binbin.hou
|
||||
@@ -61,16 +60,14 @@ public class LockAspect {
|
||||
|
||||
boolean isLockAnnotation = method.isAnnotationPresent(Lock.class);
|
||||
if(isLockAnnotation) {
|
||||
Lock lock = method.getAnnotation(Lock.class);
|
||||
Lock lockAnnotation = method.getAnnotation(Lock.class);
|
||||
|
||||
// 如果构建 key?
|
||||
String lockKey = buildLockKey(lock, point);
|
||||
String lockKey = buildLockKey(lockAnnotation, point);
|
||||
|
||||
boolean tryLockFlag = false;
|
||||
try {
|
||||
long tryLockMills = lock.tryLockMills();
|
||||
|
||||
tryLockFlag = lockBs.tryLock(tryLockMills, TimeUnit.MILLISECONDS, lockKey);
|
||||
tryLockFlag = lockBs.tryLock(lockKey, lockAnnotation.timeUnit(), lockAnnotation.lockTime(), lockAnnotation.waitLockTime());
|
||||
if(!tryLockFlag) {
|
||||
log.warn("[LOCK] TRY LOCK FAILED {}", lockKey);
|
||||
throw new LockException("[LOCK] TRY LOCK FAILED " + lockKey);
|
||||
@@ -84,7 +81,9 @@ public class LockAspect {
|
||||
// 只有获取锁的情况下,才尝试释放锁
|
||||
if(tryLockFlag) {
|
||||
boolean unLockFlag = lockBs.unlock(lockKey);
|
||||
// 异常处理等
|
||||
|
||||
// 释放锁结果
|
||||
this.lockReleaseFailHandle(unLockFlag, lockKey);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -92,6 +91,24 @@ public class LockAspect {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 锁释放失败
|
||||
* @param unLockFlag 释放结果
|
||||
* @param lockKey 加锁信息
|
||||
*/
|
||||
private void lockReleaseFailHandle(boolean unLockFlag,
|
||||
String lockKey) {
|
||||
if(unLockFlag) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 触发通知,便于用户自定义处理。
|
||||
// 比如报警
|
||||
LockReleaseFailHandlerContext handlerContext = LockReleaseFailHandlerContext.newInstance()
|
||||
.key(lockKey);
|
||||
this.lockBs.lockReleaseFailHandler().handle(handlerContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建加锁的 key
|
||||
*
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.github.houbb.lock.spring.config;
|
||||
|
||||
import com.github.houbb.redis.config.spring.annotation.EnableRedisConfig;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* bean 配置
|
||||
*
|
||||
* @author binbin.hou
|
||||
* @since 0.0.2
|
||||
*/
|
||||
@Configuration
|
||||
@EnableRedisConfig
|
||||
public class CommonCacheConfig {
|
||||
|
||||
}
|
||||
@@ -1,14 +1,12 @@
|
||||
package com.github.houbb.lock.spring.config;
|
||||
|
||||
import com.github.houbb.common.cache.api.service.ICommonCacheService;
|
||||
import com.github.houbb.heaven.util.lang.StringUtil;
|
||||
import com.github.houbb.id.api.Id;
|
||||
import com.github.houbb.id.core.core.Ids;
|
||||
import com.github.houbb.lock.api.core.ILockKeyFormat;
|
||||
import com.github.houbb.lock.api.core.ILockReleaseFailHandler;
|
||||
import com.github.houbb.lock.core.bs.LockBs;
|
||||
import com.github.houbb.lock.spring.annotation.EnableLock;
|
||||
import com.github.houbb.redis.config.core.factory.JedisRedisServiceFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.context.annotation.*;
|
||||
@@ -23,20 +21,21 @@ import org.springframework.core.type.AnnotationMetadata;
|
||||
*/
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = "com.github.houbb.lock.spring")
|
||||
@Import({LockBeanConfig.class, CommonCacheConfig.class})
|
||||
@Import({LockBeanConfig.class})
|
||||
public class LockAopConfig implements ImportAware, BeanFactoryPostProcessor {
|
||||
|
||||
@Bean("lockBs")
|
||||
public LockBs lockBs() {
|
||||
int lockExpireMills = (int) enableLockAttributes.get("lockExpireMills");
|
||||
ICommonCacheService commonCacheService = beanFactory.getBean(enableLockAttributes.getString("cache"), ICommonCacheService.class);
|
||||
Id id = beanFactory.getBean(enableLockAttributes.getString("id"), Id.class);
|
||||
ILockKeyFormat lockKeyFormat = beanFactory.getBean(enableLockAttributes.getString("lockKeyFormat"), ILockKeyFormat.class);
|
||||
ILockReleaseFailHandler lockReleaseFailHandler = beanFactory.getBean(enableLockAttributes.getString("lockReleaseFailHandler"), ILockReleaseFailHandler.class);
|
||||
|
||||
return LockBs.newInstance()
|
||||
.cache(commonCacheService)
|
||||
.id(id)
|
||||
.lockExpireMills(lockExpireMills)
|
||||
.init();
|
||||
.lockKeyFormat(lockKeyFormat)
|
||||
.lockReleaseFailHandler(lockReleaseFailHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,10 @@ package com.github.houbb.lock.spring.config;
|
||||
|
||||
import com.github.houbb.id.api.Id;
|
||||
import com.github.houbb.id.core.core.Ids;
|
||||
import com.github.houbb.lock.api.core.ILockKeyFormat;
|
||||
import com.github.houbb.lock.api.core.ILockReleaseFailHandler;
|
||||
import com.github.houbb.lock.core.support.format.LockKeyFormat;
|
||||
import com.github.houbb.lock.core.support.handler.LockReleaseFailHandler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -21,4 +25,14 @@ public class LockBeanConfig {
|
||||
return Ids.uuid32();
|
||||
}
|
||||
|
||||
@Bean("lockKeyFormat")
|
||||
public ILockKeyFormat lockKeyFormat() {
|
||||
return new LockKeyFormat();
|
||||
}
|
||||
|
||||
@Bean("lockReleaseFailHandler")
|
||||
public ILockReleaseFailHandler lockReleaseFailHandler() {
|
||||
return new LockReleaseFailHandler();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>lock</artifactId>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@@ -17,9 +17,15 @@
|
||||
<artifactId>lock-spring</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<artifactId>redis-config-springboot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.github.houbb.lock.springboot.starter.config;
|
||||
|
||||
import com.github.houbb.lock.spring.annotation.EnableLock;
|
||||
import com.github.houbb.lock.spring.config.LockAopConfig;
|
||||
import com.github.houbb.redis.config.spring.annotation.EnableRedisConfig;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>lock</artifactId>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.github.houbb.lock.test.config;
|
||||
|
||||
|
||||
import com.github.houbb.lock.spring.annotation.EnableLock;
|
||||
import com.github.houbb.redis.config.spring.annotation.EnableRedisConfig;
|
||||
import org.springframework.beans.factory.annotation.Configurable;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@@ -12,5 +13,6 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
@Configurable
|
||||
@ComponentScan(basePackages = "com.github.houbb.lock.test.service")
|
||||
@EnableLock
|
||||
@EnableRedisConfig
|
||||
public class SpringConfig {
|
||||
}
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
package com.github.houbb.lock.test.core;
|
||||
|
||||
|
||||
import com.github.houbb.id.core.core.Ids;
|
||||
import com.github.houbb.lock.api.core.ILock;
|
||||
import com.github.houbb.lock.core.bs.LockBs;
|
||||
import com.github.houbb.lock.core.support.format.LockKeyFormat;
|
||||
import com.github.houbb.lock.core.support.handler.LockReleaseFailHandler;
|
||||
import com.github.houbb.lock.core.support.lock.RedisLockSupport;
|
||||
import com.github.houbb.redis.config.core.factory.JedisRedisServiceFactory;
|
||||
import org.junit.Test;
|
||||
|
||||
public class LockBsTest {
|
||||
|
||||
@Test
|
||||
public void helloTest() {
|
||||
ILock lock = LockBs.newInstance()
|
||||
.init();
|
||||
|
||||
ILock lock = LockBs.newInstance();
|
||||
String key = "ddd";
|
||||
try {
|
||||
// 加锁
|
||||
@@ -25,4 +28,15 @@ public class LockBsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configTest() {
|
||||
LockBs.newInstance()
|
||||
.id(Ids.uuid32()) //id 生成策略
|
||||
.cache(JedisRedisServiceFactory.pooled("127.0.0.1", 6379)) //缓存策略
|
||||
.lockSupport(new RedisLockSupport()) // 锁实现策略
|
||||
.lockKeyFormat(new LockKeyFormat()) // 针对 key 的格式化处理策略
|
||||
.lockReleaseFailHandler(new LockReleaseFailHandler()) //释放锁失败处理
|
||||
;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>lock</artifactId>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<version>1.1.0</version>
|
||||
<version>1.3.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
7
pom.xml
7
pom.xml
@@ -5,7 +5,7 @@
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<artifactId>lock</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<version>1.1.0</version>
|
||||
<version>1.3.0</version>
|
||||
<modules>
|
||||
<module>lock-api</module>
|
||||
<module>lock-core</module>
|
||||
@@ -123,6 +123,11 @@
|
||||
<artifactId>redis-config-spring</artifactId>
|
||||
<version>${redis-config.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.houbb</groupId>
|
||||
<artifactId>redis-config-springboot-starter</artifactId>
|
||||
<version>${redis-config.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--============================== OTHER ==============================-->
|
||||
<dependency>
|
||||
|
||||
@@ -10,9 +10,9 @@ ECHO "============================= RELEASE START..."
|
||||
|
||||
:: 版本号信息(需要手动指定)
|
||||
:::: 旧版本名称
|
||||
SET version=1.1.0
|
||||
SET version=1.3.0
|
||||
:::: 新版本名称
|
||||
SET newVersion=1.2.0
|
||||
SET newVersion=1.4.0
|
||||
:::: 组织名称
|
||||
SET groupName=com.github.houbb
|
||||
:::: 项目名称
|
||||
|
||||
Reference in New Issue
Block a user