release branch 1.1.0
This commit is contained in:
@@ -39,3 +39,9 @@
|
|||||||
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
||||||
|:---|:---|:---|:---|:--|
|
|:---|:---|:---|:---|:--|
|
||||||
| 1 | A | 基于 redis 实现的分布式锁策略 | 2022-12-7 14:45:40 | |
|
| 1 | A | 基于 redis 实现的分布式锁策略 | 2022-12-7 14:45:40 | |
|
||||||
|
|
||||||
|
# release_1.1.0
|
||||||
|
|
||||||
|
| 序号 | 变更类型 | 说明 | 时间 | 备注 |
|
||||||
|
|:---|:---|:---|:---|:--|
|
||||||
|
| 1 | A | 整合 spring | 2022-12-7 14:45:40 | |
|
||||||
|
|||||||
119
README.md
119
README.md
@@ -10,9 +10,13 @@
|
|||||||
|
|
||||||
- 基于 redis 的分布式锁
|
- 基于 redis 的分布式锁
|
||||||
|
|
||||||
- 基于 oracle 的分布式锁
|
- 整合 spring
|
||||||
|
|
||||||
- 基于 mysql 的分布式锁
|
- 整合 spring-boot
|
||||||
|
|
||||||
|
- 开箱即用,支持注解。
|
||||||
|
|
||||||
|
- 支持多种 redis 的声明方式
|
||||||
|
|
||||||
# 变更日志
|
# 变更日志
|
||||||
|
|
||||||
@@ -32,7 +36,7 @@ maven 3.x+
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<artifactId>lock-core</artifactId>
|
<artifactId>lock-core</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -57,21 +61,108 @@ try {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# 整合 spring
|
||||||
|
|
||||||
|
## maven 引入
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>lock-spring</artifactId>
|
||||||
|
<version>1.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 指定 bean 使用
|
||||||
|
|
||||||
|
### 启用分布式锁
|
||||||
|
|
||||||
|
`@EnableLock` 启用分布式锁。
|
||||||
|
|
||||||
|
```xml
|
||||||
|
@Configurable
|
||||||
|
@ComponentScan(basePackages = "com.github.houbb.lock.test.service")
|
||||||
|
@EnableLock
|
||||||
|
public class SpringConfig {
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 使用 LockBs
|
||||||
|
|
||||||
|
我们可以直接 `LockBs` 的引导类。
|
||||||
|
|
||||||
|
```java
|
||||||
|
@ContextConfiguration(classes = SpringConfig.class)
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
public class SpringServiceRawTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LockBs lockBs;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void queryLogTest() {
|
||||||
|
final String key = "name";
|
||||||
|
try {
|
||||||
|
lockBs.tryLock(key);
|
||||||
|
final String value = userService.rawUserName(1L);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
} finally {
|
||||||
|
lockBs.unlock(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## aop 注解使用
|
||||||
|
|
||||||
|
### 指定方法注解
|
||||||
|
|
||||||
|
当然,我们可以在方法上直接指定注解 `@Lock`,使用更加方便。
|
||||||
|
|
||||||
|
支持 SPEL 表达式。
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
public class UserService {
|
||||||
|
|
||||||
|
@Lock
|
||||||
|
public String queryUserName(Long userId) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Lock(value = "#user.name")
|
||||||
|
public void queryUserName2(User user) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
直接使用,AOP 切面生效即可。
|
||||||
|
|
||||||
|
# springboot 整合
|
||||||
|
|
||||||
|
## maven 引入
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>lock-springboot-starter</artifactId>
|
||||||
|
<version>1.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用
|
||||||
|
|
||||||
|
同 spring
|
||||||
|
|
||||||
# 后期 Road-MAP
|
# 后期 Road-MAP
|
||||||
|
|
||||||
- [ ] 支持锁的可重入
|
- [ ] 支持锁的可重入
|
||||||
|
|
||||||
持有锁的线程可以多次获取锁
|
持有锁的线程可以多次获取锁
|
||||||
|
|
||||||
- [ ] redis 实现的支持
|
- [x] 分布式锁注解支持
|
||||||
|
|
||||||
cluster 支持
|
|
||||||
|
|
||||||
redis 支持
|
|
||||||
|
|
||||||
aliyun-redis 支持
|
|
||||||
|
|
||||||
各种各样的声明方式的默认支持
|
|
||||||
|
|
||||||
- [ ] 分布式锁注解支持
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -57,31 +57,29 @@ public class RedisLockSupport implements ILockSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean tryLock(String key, ILockSupportContext context) {
|
public boolean tryLock(String key, ILockSupportContext context) {
|
||||||
log.info("开始尝试获取锁 {}", key);
|
|
||||||
|
|
||||||
// 生成当前线程的唯一标识
|
// 生成当前线程的唯一标识
|
||||||
Id id = context.id();
|
Id id = context.id();
|
||||||
final String requestId = id.id();
|
final String requestId = id.id();
|
||||||
IdThreadLocalHelper.put(requestId);
|
IdThreadLocalHelper.put(requestId);
|
||||||
log.info("开始尝试获取锁 requestId: {}", requestId);
|
log.info("[LOCK] BEGIN TRY LOCK key: {} requestId: {}", key, requestId);
|
||||||
|
|
||||||
final ICommonCacheService commonCacheService = context.cache();
|
final ICommonCacheService commonCacheService = context.cache();
|
||||||
|
|
||||||
final int lockExpireMills = context.lockExpireMills();
|
final int lockExpireMills = context.lockExpireMills();
|
||||||
|
|
||||||
String result = commonCacheService.set(key, requestId, JedisConst.SET_IF_NOT_EXIST, JedisConst.SET_WITH_EXPIRE_TIME, lockExpireMills);
|
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);
|
||||||
return JedisConst.OK.equalsIgnoreCase(result);
|
return JedisConst.OK.equalsIgnoreCase(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean unlock(String key, ILockSupportContext context) {
|
public boolean unlock(String key, ILockSupportContext context) {
|
||||||
log.info("开始尝试释放锁 {}", key);
|
|
||||||
String requestId = IdThreadLocalHelper.get();
|
String requestId = IdThreadLocalHelper.get();
|
||||||
log.info("开始尝试释放锁 requestId: {}", requestId);
|
log.info("[LOCK] BEGIN UN LOCK key: {} requestId: {}", key, requestId);
|
||||||
|
|
||||||
final ICommonCacheService commonCacheService = context.cache();
|
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";
|
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));
|
Object result = commonCacheService.eval(script, Collections.singletonList(key), Collections.singletonList(requestId));
|
||||||
|
log.info("[LOCK] END UN LOCK key: {}, requestId: {}, result: {}", key, requestId, result);
|
||||||
return JedisConst.RELEASE_SUCCESS.equals(result);
|
return JedisConst.RELEASE_SUCCESS.equals(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@@ -25,6 +25,11 @@
|
|||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<artifactId>aop-spring</artifactId>
|
<artifactId>aop-spring</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>redis-config-spring</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@@ -34,10 +34,13 @@ public @interface EnableLock {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存实现策略 bean 名称
|
* 缓存实现策略 bean 名称
|
||||||
|
*
|
||||||
|
* 默认引入 redis-config 中的配置
|
||||||
|
*
|
||||||
* @return 实现
|
* @return 实现
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
*/
|
*/
|
||||||
String cache() default "lockCache";
|
String cache() default "springRedisService";
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package com.github.houbb.lock.spring.aop;
|
|||||||
import com.github.houbb.aop.spring.util.SpringAopUtil;
|
import com.github.houbb.aop.spring.util.SpringAopUtil;
|
||||||
import com.github.houbb.heaven.util.lang.ObjectUtil;
|
import com.github.houbb.heaven.util.lang.ObjectUtil;
|
||||||
import com.github.houbb.heaven.util.lang.StringUtil;
|
import com.github.houbb.heaven.util.lang.StringUtil;
|
||||||
import com.github.houbb.heaven.util.lang.reflect.ReflectMethodUtil;
|
|
||||||
import com.github.houbb.heaven.util.util.ArrayUtil;
|
import com.github.houbb.heaven.util.util.ArrayUtil;
|
||||||
import com.github.houbb.lock.api.exception.LockException;
|
import com.github.houbb.lock.api.exception.LockException;
|
||||||
import com.github.houbb.lock.core.bs.LockBs;
|
import com.github.houbb.lock.core.bs.LockBs;
|
||||||
@@ -11,9 +10,11 @@ import com.github.houbb.lock.spring.annotation.Lock;
|
|||||||
import com.github.houbb.log.integration.core.Log;
|
import com.github.houbb.log.integration.core.Log;
|
||||||
import com.github.houbb.log.integration.core.LogFactory;
|
import com.github.houbb.log.integration.core.LogFactory;
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
import org.aspectj.lang.ProceedingJoinPoint;
|
||||||
|
import org.aspectj.lang.Signature;
|
||||||
import org.aspectj.lang.annotation.Around;
|
import org.aspectj.lang.annotation.Around;
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
import org.aspectj.lang.annotation.Pointcut;
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.expression.EvaluationContext;
|
import org.springframework.expression.EvaluationContext;
|
||||||
@@ -23,8 +24,8 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Parameter;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -63,15 +64,16 @@ public class LockAspect {
|
|||||||
Lock lock = method.getAnnotation(Lock.class);
|
Lock lock = method.getAnnotation(Lock.class);
|
||||||
|
|
||||||
// 如果构建 key?
|
// 如果构建 key?
|
||||||
Object[] args = point.getArgs();
|
String lockKey = buildLockKey(lock, point);
|
||||||
String lockKey = buildLockKey(lock, method, args);
|
|
||||||
|
boolean tryLockFlag = false;
|
||||||
try {
|
try {
|
||||||
long tryLockMills = lock.tryLockMills();
|
long tryLockMills = lock.tryLockMills();
|
||||||
|
|
||||||
boolean tryLockFlag = lockBs.tryLock(tryLockMills, TimeUnit.MILLISECONDS, lockKey);
|
tryLockFlag = lockBs.tryLock(tryLockMills, TimeUnit.MILLISECONDS, lockKey);
|
||||||
if(!tryLockFlag) {
|
if(!tryLockFlag) {
|
||||||
log.warn("尝试获取锁失败 {}", lockKey);
|
log.warn("[LOCK] TRY LOCK FAILED {}", lockKey);
|
||||||
throw new LockException("尝试获取锁失败 " + lockKey);
|
throw new LockException("[LOCK] TRY LOCK FAILED " + lockKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 执行业务
|
// 执行业务
|
||||||
@@ -79,10 +81,10 @@ public class LockAspect {
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
} finally {
|
} finally {
|
||||||
boolean unLockFlag = lockBs.unlock(lockKey);
|
// 只有获取锁的情况下,才尝试释放锁
|
||||||
if(!unLockFlag) {
|
if(tryLockFlag) {
|
||||||
log.warn("尝试释放锁失败 {}", lockKey);
|
boolean unLockFlag = lockBs.unlock(lockKey);
|
||||||
// 这里释放异常,没有意义。
|
// 异常处理等
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -97,19 +99,19 @@ public class LockAspect {
|
|||||||
*
|
*
|
||||||
* https://www.cnblogs.com/best/p/5748105.html SpEL
|
* https://www.cnblogs.com/best/p/5748105.html SpEL
|
||||||
* @param lock 注解信息
|
* @param lock 注解信息
|
||||||
* @param args 参数
|
* @param joinPoint 参数
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
private String buildLockKey(Lock lock,
|
private String buildLockKey(Lock lock,
|
||||||
Method method,
|
ProceedingJoinPoint joinPoint) {
|
||||||
Object[] args) {
|
final Object[] args = joinPoint.getArgs();
|
||||||
final String lockValue = lock.value();
|
final String lockValue = lock.value();
|
||||||
|
|
||||||
//创建SpEL表达式的解析器
|
//创建SpEL表达式的解析器
|
||||||
ExpressionParser parser = new SpelExpressionParser();
|
ExpressionParser parser = new SpelExpressionParser();
|
||||||
//1. 如果没有入参怎么办?
|
//1. 如果没有入参怎么办?
|
||||||
if(ArrayUtil.isEmpty(args)) {
|
if(ArrayUtil.isEmpty(args)) {
|
||||||
log.warn("对应的数组信息为空,直接返回 key 的值 {}", lockValue);
|
log.warn("[LOCK] method args is empty, return lock.value() {}", lockValue);
|
||||||
return lockValue;
|
return lockValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,10 +125,14 @@ public class LockAspect {
|
|||||||
//解析表达式需要的上下文,解析时有一个默认的上下文
|
//解析表达式需要的上下文,解析时有一个默认的上下文
|
||||||
// jdk1.7 之前,直接使用 arg0, arg1...
|
// jdk1.7 之前,直接使用 arg0, arg1...
|
||||||
EvaluationContext ctx = new StandardEvaluationContext();
|
EvaluationContext ctx = new StandardEvaluationContext();
|
||||||
List<String> paramNameList = ReflectMethodUtil.getParamNames(method);
|
|
||||||
|
|
||||||
for(int i = 0; i < paramNameList.size(); i++) {
|
// 利用 spring 的处理方式
|
||||||
String paramName = paramNameList.get(i);
|
Signature signature = joinPoint.getSignature();
|
||||||
|
MethodSignature methodSignature = (MethodSignature) signature;
|
||||||
|
String[] paramNameList = methodSignature.getParameterNames();
|
||||||
|
|
||||||
|
for(int i = 0; i < paramNameList.length; i++) {
|
||||||
|
String paramName = paramNameList[i];
|
||||||
Object paramValue = args[i];
|
Object paramValue = args[i];
|
||||||
|
|
||||||
//在上下文中设置变量,变量名为user,内容为user对象
|
//在上下文中设置变量,变量名为user,内容为user对象
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
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 {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ import org.springframework.core.type.AnnotationMetadata;
|
|||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ComponentScan(basePackages = "com.github.houbb.lock.spring")
|
@ComponentScan(basePackages = "com.github.houbb.lock.spring")
|
||||||
@Import(LockBeanConfig.class)
|
@Import({LockBeanConfig.class, CommonCacheConfig.class})
|
||||||
public class LockAopConfig implements ImportAware, BeanFactoryPostProcessor {
|
public class LockAopConfig implements ImportAware, BeanFactoryPostProcessor {
|
||||||
|
|
||||||
@Bean("lockBs")
|
@Bean("lockBs")
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
package com.github.houbb.lock.spring.config;
|
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.api.Id;
|
||||||
import com.github.houbb.id.core.core.Ids;
|
import com.github.houbb.id.core.core.Ids;
|
||||||
import com.github.houbb.redis.config.core.factory.JedisRedisServiceFactory;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@@ -20,24 +16,6 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
@ComponentScan(basePackages = "com.github.houbb.lock.spring")
|
@ComponentScan(basePackages = "com.github.houbb.lock.spring")
|
||||||
public class LockBeanConfig {
|
public class LockBeanConfig {
|
||||||
|
|
||||||
@Value("${redis.address:127.0.0.1}")
|
|
||||||
private String redisAddress;
|
|
||||||
|
|
||||||
@Value("${redis.port:6379}")
|
|
||||||
private int redisPort;
|
|
||||||
|
|
||||||
@Value("${redis.password:}")
|
|
||||||
private String redisPassword;
|
|
||||||
|
|
||||||
@Bean("lockCache")
|
|
||||||
public ICommonCacheService lockCache() {
|
|
||||||
if(StringUtil.isNotEmpty(redisPassword)) {
|
|
||||||
return JedisRedisServiceFactory.pooled(redisAddress, redisPort, redisPassword);
|
|
||||||
}
|
|
||||||
|
|
||||||
return JedisRedisServiceFactory.simple(redisAddress, redisPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean("lockId")
|
@Bean("lockId")
|
||||||
public Id lockId() {
|
public Id lockId() {
|
||||||
return Ids.uuid32();
|
return Ids.uuid32();
|
||||||
|
|||||||
25
lock-springboot-starter/pom.xml
Normal file
25
lock-springboot-starter/pom.xml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>lock</artifactId>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<version>1.1.0</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>lock-springboot-starter</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>lock-spring</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分布式锁自动配置
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@ConditionalOnClass(LockAutoConfig.class)
|
||||||
|
@EnableLock
|
||||||
|
public class LockAutoConfig {
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* @author d
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
package com.github.houbb.lock.springboot.starter;
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.github.houbb.lock.springboot.starter.config.LockAutoConfig
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@@ -30,6 +30,23 @@
|
|||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<artifactId>test-spring</artifactId>
|
<artifactId>test-spring</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>slf4j-common</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-core</artifactId>
|
||||||
|
<version>1.1.11</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>1.1.11</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -11,12 +11,16 @@ import org.springframework.stereotype.Service;
|
|||||||
@Service
|
@Service
|
||||||
public class UserService {
|
public class UserService {
|
||||||
|
|
||||||
|
public String rawUserName(Long userId) {
|
||||||
|
return userId+"-name";
|
||||||
|
}
|
||||||
|
|
||||||
@Lock
|
@Lock
|
||||||
public String queryUserName(Long userId) {
|
public String queryUserName(Long userId) {
|
||||||
return userId+"-name";
|
return userId+"-name";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Lock(value = "#arg0.name")
|
@Lock(value = "#user.name")
|
||||||
public void queryUserName2(User user) {
|
public void queryUserName2(User user) {
|
||||||
System.out.println("user: " + user.toString());
|
System.out.println("user: " + user.toString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.github.houbb.lock.test.spring;
|
||||||
|
|
||||||
|
|
||||||
|
import com.github.houbb.lock.core.bs.LockBs;
|
||||||
|
import com.github.houbb.lock.test.config.SpringConfig;
|
||||||
|
import com.github.houbb.lock.test.model.User;
|
||||||
|
import com.github.houbb.lock.test.service.UserService;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
@ContextConfiguration(classes = SpringConfig.class)
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
public class SpringServiceRawTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LockBs lockBs;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void queryLogTest() {
|
||||||
|
final String key = "name";
|
||||||
|
try {
|
||||||
|
lockBs.tryLock(key);
|
||||||
|
final String value = userService.rawUserName(1L);
|
||||||
|
} catch (Exception exception) {
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
} finally {
|
||||||
|
lockBs.unlock(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
23
lock-test/src/test/resources/logback.xml
Normal file
23
lock-test/src/test/resources/logback.xml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration debug="false">
|
||||||
|
|
||||||
|
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 /app/sv/logs -->
|
||||||
|
<!-- 控制台输出 -->
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
|
||||||
|
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
|
||||||
|
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
|
||||||
|
<charset>utf-8</charset>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!--com.github.houbb 包路径 additivity: 表示是否 想上层传递)-->
|
||||||
|
<logger name="com.github.houbb.lock" level="INFO" additivity="true">
|
||||||
|
</logger>
|
||||||
|
|
||||||
|
<!-- 日志输出级别-->
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT"/>
|
||||||
|
</root>
|
||||||
|
|
||||||
|
</configuration>
|
||||||
47
lock-test2/pom.xml
Normal file
47
lock-test2/pom.xml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>lock</artifactId>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<version>1.1.0</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>lock-test2</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>lock-springboot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>test-spring</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>slf4j-common</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-core</artifactId>
|
||||||
|
<version>1.1.11</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ch.qos.logback</groupId>
|
||||||
|
<artifactId>logback-classic</artifactId>
|
||||||
|
<version>1.1.11</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* @author d
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
package com.github.houbb.lock.test2;
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.github.houbb.lock.test2.service;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 0.0.3
|
||||||
|
*/
|
||||||
|
@SpringBootApplication
|
||||||
|
public class MyApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(MyApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.github.houbb.lock.test2.service;
|
||||||
|
|
||||||
|
import com.github.houbb.lock.spring.annotation.Lock;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 0.0.1
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class UserService {
|
||||||
|
|
||||||
|
@Lock
|
||||||
|
public void queryInfo(final String id) {
|
||||||
|
System.out.println("query info: " + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.github.houbb.lock.test2.service;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author binbin.hou
|
||||||
|
* @since 0.0.2
|
||||||
|
*/
|
||||||
|
@ContextConfiguration(classes = MyApplication.class)
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
public class UserServiceTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserService service;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void queryTest() {
|
||||||
|
service.queryInfo("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
/**
|
||||||
|
* @author d
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
package com.github.houbb.lock.test2.service;
|
||||||
28
pom.xml
28
pom.xml
@@ -5,12 +5,14 @@
|
|||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<artifactId>lock</artifactId>
|
<artifactId>lock</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>1.0.0</version>
|
<version>1.1.0</version>
|
||||||
<modules>
|
<modules>
|
||||||
<module>lock-api</module>
|
<module>lock-api</module>
|
||||||
<module>lock-core</module>
|
<module>lock-core</module>
|
||||||
<module>lock-test</module>
|
<module>lock-test</module>
|
||||||
<module>lock-spring</module>
|
<module>lock-spring</module>
|
||||||
|
<module>lock-springboot-starter</module>
|
||||||
|
<module>lock-test2</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@@ -46,7 +48,7 @@
|
|||||||
|
|
||||||
<!--============================== OTHER ==============================-->
|
<!--============================== OTHER ==============================-->
|
||||||
<junit.version>4.12</junit.version>
|
<junit.version>4.12</junit.version>
|
||||||
<jedis.version>2.8.1</jedis.version>
|
<spring-boot.version>1.5.22.RELEASE</spring-boot.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
@@ -67,6 +69,11 @@
|
|||||||
<artifactId>lock-spring</artifactId>
|
<artifactId>lock-spring</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>lock-springboot-starter</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--============================== INTER ==============================-->
|
<!--============================== INTER ==============================-->
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -111,6 +118,11 @@
|
|||||||
<artifactId>redis-config-core</artifactId>
|
<artifactId>redis-config-core</artifactId>
|
||||||
<version>${redis-config.version}</version>
|
<version>${redis-config.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.houbb</groupId>
|
||||||
|
<artifactId>redis-config-spring</artifactId>
|
||||||
|
<version>${redis-config.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!--============================== OTHER ==============================-->
|
<!--============================== OTHER ==============================-->
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -121,12 +133,6 @@
|
|||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>redis.clients</groupId>
|
|
||||||
<artifactId>jedis</artifactId>
|
|
||||||
<version>${jedis.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.houbb</groupId>
|
<groupId>com.github.houbb</groupId>
|
||||||
<artifactId>aop-core</artifactId>
|
<artifactId>aop-core</artifactId>
|
||||||
@@ -144,6 +150,12 @@
|
|||||||
<version>${test.version}</version>
|
<version>${test.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ ECHO "============================= RELEASE START..."
|
|||||||
|
|
||||||
:: 版本号信息(需要手动指定)
|
:: 版本号信息(需要手动指定)
|
||||||
:::: 旧版本名称
|
:::: 旧版本名称
|
||||||
SET version=1.0.0
|
SET version=1.1.0
|
||||||
:::: 新版本名称
|
:::: 新版本名称
|
||||||
SET newVersion=1.1.0
|
SET newVersion=1.2.0
|
||||||
:::: 组织名称
|
:::: 组织名称
|
||||||
SET groupName=com.github.houbb
|
SET groupName=com.github.houbb
|
||||||
:::: 项目名称
|
:::: 项目名称
|
||||||
|
|||||||
Reference in New Issue
Block a user