From fa23a4415972d5fcc1589c91bbf0d37a47d8dd40 Mon Sep 17 00:00:00 2001 From: huangchengxing <841396397@qq.com> Date: Mon, 22 Apr 2024 23:55:35 +0800 Subject: [PATCH] =?UTF-8?q?doc:=20=E4=BC=98=E5=8C=96=E6=B3=A8=E9=87=8A?= =?UTF-8?q?=EF=BC=8C=E8=B0=83=E6=95=B4=E5=8F=82=E6=95=B0=E5=90=8D=E7=A7=B0?= =?UTF-8?q?=E4=B8=8E=E6=96=B9=E6=B3=95=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../baomidou/lock/LockFailureStrategy.java | 1 + .../com/baomidou/lock/LockKeyBuilder.java | 4 +- .../baomidou/lock/annotation/LocalLock.java | 98 +++++++--- .../com/baomidou/lock/annotation/Lock4j.java | 178 +++++++++++++++--- .../lock/annotation/LockWithDefault.java | 91 ++++++--- .../baomidou/lock/aop/LockOpsInterceptor.java | 1 + .../lock/executor/LocalLockExecutor.java | 2 + .../baomidou/lock/executor/LockExecutor.java | 21 ++- .../baomidou/lock/annotation/RedisLock.java | 99 +++++++--- .../executor/RedisTemplateLockExecutor.java | 4 +- .../lock/annotation/RedissonLock.java | 98 +++++++--- .../lock/executor/RedissonLockExecutor.java | 4 +- .../lock/annotation/ZookeeperLock.java | 108 ++++++++--- .../lock/executor/ZookeeperLockExecutor.java | 2 + 14 files changed, 549 insertions(+), 162 deletions(-) diff --git a/lock4j-core/src/main/java/com/baomidou/lock/LockFailureStrategy.java b/lock4j-core/src/main/java/com/baomidou/lock/LockFailureStrategy.java index e2e5d21..9b15241 100644 --- a/lock4j-core/src/main/java/com/baomidou/lock/LockFailureStrategy.java +++ b/lock4j-core/src/main/java/com/baomidou/lock/LockFailureStrategy.java @@ -33,6 +33,7 @@ public interface LockFailureStrategy { * @param arguments 方法参数 * @throws Exception 处理过程中可能抛出的异常,如果抛出异常则会终止方法执行 */ + @SuppressWarnings("java:S112") void onLockFailure(String key, Method method, Object[] arguments) throws Exception; // TODO 释放锁失败时也应该进行处理,具体参见:https://gitee.com/baomidou/lock4j/issues/I4LG1U diff --git a/lock4j-core/src/main/java/com/baomidou/lock/LockKeyBuilder.java b/lock4j-core/src/main/java/com/baomidou/lock/LockKeyBuilder.java index 031e069..6299b5c 100644 --- a/lock4j-core/src/main/java/com/baomidou/lock/LockKeyBuilder.java +++ b/lock4j-core/src/main/java/com/baomidou/lock/LockKeyBuilder.java @@ -19,6 +19,8 @@ package com.baomidou.lock; import org.aopalliance.intercept.MethodInvocation; /** + * 用于加锁的key生成器 + * * @author zengzhihong */ public interface LockKeyBuilder { @@ -26,7 +28,7 @@ public interface LockKeyBuilder { /** * 构建key * - * @param invocation invocation + * @param invocation 方法调用 * @param definitionKeys 定义 * @return key */ diff --git a/lock4j-core/src/main/java/com/baomidou/lock/annotation/LocalLock.java b/lock4j-core/src/main/java/com/baomidou/lock/annotation/LocalLock.java index 734cc98..02e3298 100644 --- a/lock4j-core/src/main/java/com/baomidou/lock/annotation/LocalLock.java +++ b/lock4j-core/src/main/java/com/baomidou/lock/annotation/LocalLock.java @@ -3,8 +3,10 @@ package com.baomidou.lock.annotation; import com.baomidou.lock.LockFailureStrategy; import com.baomidou.lock.LockKeyBuilder; import com.baomidou.lock.executor.LocalLockExecutor; +import com.baomidou.lock.executor.LockExecutor; import com.baomidou.lock.spring.boot.autoconfigure.Lock4jProperties; import org.springframework.core.Ordered; +import org.springframework.core.annotation.AliasFor; import java.lang.annotation.*; @@ -20,65 +22,111 @@ import java.lang.annotation.*; public @interface LocalLock { /** - * 应用条件表达式,当执行结果为{@code true}或{@code 'true'}时,才会执行锁操作 + *
应用条件表达式,当执行结果为{@code true}或{@code 'true'}时,才会执行锁操作。 * - * @return 名称 + *
你可以在表达式中引用上下文参数: + *
key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面, + * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。 + * + * @return key前缀 + */ + @AliasFor("name") + String prefix() default ""; + + /** + *
key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面, + * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。 * - * @return 名称 + * @return key前缀 */ + @AliasFor("prefix") String name() default ""; /** - * support SPEL expresion 锁的key = name + keys + * 要用于加锁的key,执行时, + * 将通过{@link #keyBuilderStrategy()}指定的策略生成最终的key。 * - * @return KEY + * @return 要加锁的key + * @see #keyBuilderStrategy() + * @see LockKeyBuilder */ String[] keys() default ""; /** - * @return 过期时间 单位:毫秒 - *
- * 过期时间一定是要长于业务的执行时间. 未设置则为默认时间30秒 默认值:{@link Lock4jProperties#expire} - *+ *
要使用的{@link LockKeyBuilder key生成器}类型, + * 默认优先使用{@link Lock4jProperties#getPrimaryKeyBuilder()} Lck4jProperties.primaryKeyBuilder}所指定的执行器。 + * + * @return 生成器类型 + * @see LockKeyBuilder */ - long expire() default -1; + Class extends LockKeyBuilder> keyBuilderStrategy() default LockKeyBuilder.class; /** - * @return 获取锁超时时间 单位:毫秒 - *
- * 结合业务,建议该时间不宜设置过长,特别在并发高的情况下. 未设置则为默认时间3秒 默认值:{@link Lock4jProperties#acquireTimeout} - *+ *
获取锁超时时间,单位为毫秒。 + *
注意:并发较高的情况下该值不易设置过大,请结合业务设置一个合理的等待时间。 + * + * @return 获取锁超时时间 + * @see #failStrategy() */ long acquireTimeout() default -1; /** - * 业务方法执行完后(方法内抛异常也算执行完)自动释放锁,如果为false,锁将不会自动释放直至到达过期时间才释放 {@link com.baomidou.lock.annotation.Lock4j#expire()} + *
锁的过期时间,单位为毫秒。 * - * @return 是否自动释放锁 + *
当该值小于等于0时,若所使用的{@link #executor() 执行器}支持自动续期,
+ * 则在业务执行期间将会自动续期,直至业务执行完毕后才会释放锁。
+ * 否则会使用{@link Lock4jProperties#getExpire() Lck4jProperties.expire}指定的过期时间。
+ *
+ *
注意:过期时间请务必保证长于业务的执行时间,未在配置文件中指定超时时间时,则默认为30s。 + * + * @return 锁的过期时间 + * @see LockExecutor#supportRenewal() + * @see #autoRelease() */ - boolean autoRelease() default true; + long expire() default -1; /** - * 失败策略 + *
在方法执行完后是否自动释放锁, + * 当设置为{@code false}时,锁将不会自动释放,直至到达过期时间才会释放。 * - * @return LockFailureStrategy + * @return 是否自动释放锁 */ - Class extends LockFailureStrategy> failStrategy() default LockFailureStrategy.class; + boolean autoRelease() default true; /** - * key生成器策略 + *
要使用的{@link LockFailureStrategy 当获取锁失败时的处理策略}类型, + * 默认优先使用{@link Lock4jProperties#getPrimaryFailureStrategy()} Lck4jProperties.primaryFailureStrategy}所指定的执行器。 * - * @return LockKeyBuilder + * @return 失败策略类型 + * @see LockFailureStrategy */ - Class extends LockKeyBuilder> keyBuilderStrategy() default LockKeyBuilder.class; + Class extends LockFailureStrategy> failStrategy() default LockFailureStrategy.class; /** - * 获取顺序,值越小越先执行 + *
当存在多个{@link Lock4j}注解时, + * 将会根据该值进行排序,顺序值越小越先执行。 * * @return 顺序值 */ diff --git a/lock4j-core/src/main/java/com/baomidou/lock/annotation/Lock4j.java b/lock4j-core/src/main/java/com/baomidou/lock/annotation/Lock4j.java index dfca5fc..b3648bc 100644 --- a/lock4j-core/src/main/java/com/baomidou/lock/annotation/Lock4j.java +++ b/lock4j-core/src/main/java/com/baomidou/lock/annotation/Lock4j.java @@ -21,13 +21,80 @@ import com.baomidou.lock.LockKeyBuilder; import com.baomidou.lock.executor.LockExecutor; import com.baomidou.lock.spring.boot.autoconfigure.Lock4jProperties; import org.springframework.core.Ordered; +import org.springframework.core.annotation.AliasFor; +import org.springframework.core.annotation.MergedAnnotation; import java.lang.annotation.*; /** - * 分布式锁注解 + *
AOP注解,标明注解方法在执行前需要获取锁。 * - * @author zengzhihong TaoYu + *
{@code + * @Lock4j(prefix = "example", key = "lock:global", acquireTimeout = 10L, expire = 20L) + * void runWithLock(); + * }+ * 在上述例子中,将会获取一个名为{@code "example:lock:global"}的锁,等待时间为10ms,超时时间为20ms。 + * + *
{@code + * @Lock4j(key = "lock:global", condition = "#ids =! null && !#ids.isEmpty()") + * void runWithLock(Collection+ * 在上述例子中,仅当入参参数{@code ids}不为空时才会加锁。 + * + *ids); + * }
{@code + * @Lock4j(key = {"#id", "':three'"}, order = 3) + * @Lock4j(key = {"#id", "':two'"}, order = 2) + * @Lock4j(key = {"#id", "':one'"}, order = 1) + * void runWithLock(Integer id); + * }+ * 在上述例子中,将会依次获取三把锁,等到执行完毕后,将会再依次释放。 + * + *
{@code + * @Lock4j( + * key = "'lock:' + #{id}", + * keyBuilderStrategy = DefaultKeyBuilderStrategy.class, // 基于 SpEL 表达式生成 key + * executor = RedissonLockExecutor.clas, // 基于 Redisson 加锁 + * failStrategy = AbortLockFailureStrategy.class, // 加锁失败后,直接抛出AppException + * acquireTimeout = 10L, expire = 20L + * ) + * void runWithLock(Integer id); + * }+ * 若要实现自己的组件,则实现接口后将实现类托管到Spring容器后,即可在注解中引用。 + * + *
{@code + * @Lock4j(keys ="global:lock") // 将@Lock4j作为元注解 + * @Documented + * @Target(ElementType.METHOD) + * @Retention(RetentionPolicy.RUNTIME) + * public @interface GlobalLocked {} + * }+ * 当使用扩展注解{@code @GlobalLocked} 时,其等效于{@code @Lock4j(keys ="global:lock")}。
应用条件表达式,当执行结果为{@code true}或{@code 'true'}时,才会执行锁操作。 + * + *
你可以在表达式中引用上下文参数: + *
key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面, + * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。 * - * @return 名称 + * @return key前缀 */ + @AliasFor("name") + String prefix() default ""; + + /** + *
key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面, + * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。 + * + * @return key前缀 + */ + @AliasFor("prefix") String name() default ""; /** - * @return lock 执行器 + *
要使用的{@link LockExecutor 锁执行器}类型, + * 默认优先使用{@link Lock4jProperties#getPrimaryExecutor() Lck4jProperties.primaryExecutor}所指定的执行器, + * + * @return 执行器类型 + * @see LockExecutor */ Class extends LockExecutor> executor() default LockExecutor.class; /** - * support SPEL expresion 锁的key = name + keys + * 要用于加锁的key,执行时, + * 将通过{@link #keyBuilderStrategy()}指定的策略生成最终的key。 * - * @return KEY + * @return 要加锁的key + * @see #keyBuilderStrategy() + * @see LockKeyBuilder */ String[] keys() default ""; /** - * @return 过期时间 单位:毫秒 - *
- * 过期时间一定是要长于业务的执行时间. 未设置则为默认时间30秒 默认值:{@link Lock4jProperties#expire} - *+ *
要使用的{@link LockKeyBuilder key生成器}类型, + * 默认优先使用{@link Lock4jProperties#getPrimaryKeyBuilder()} Lck4jProperties.primaryKeyBuilder}所指定的执行器。 + * + * @return 生成器类型 + * @see LockKeyBuilder */ - long expire() default -1; + Class extends LockKeyBuilder> keyBuilderStrategy() default LockKeyBuilder.class; /** - * @return 获取锁超时时间 单位:毫秒 - *
- * 结合业务,建议该时间不宜设置过长,特别在并发高的情况下. 未设置则为默认时间3秒 默认值:{@link Lock4jProperties#acquireTimeout} - *+ *
获取锁超时时间,单位为毫秒。 + *
注意:并发较高的情况下该值不易设置过大,请结合业务设置一个合理的等待时间。 + * + * @return 获取锁超时时间 + * @see #failStrategy() */ long acquireTimeout() default -1; /** - * 业务方法执行完后(方法内抛异常也算执行完)自动释放锁,如果为false,锁将不会自动释放直至到达过期时间才释放 {@link com.baomidou.lock.annotation.Lock4j#expire()} + *
锁的过期时间,单位为毫秒。 * - * @return 是否自动释放锁 + *
当该值小于等于0时,若所使用的{@link #executor() 执行器}支持自动续期,
+ * 则在业务执行期间将会自动续期,直至业务执行完毕后才会释放锁。
+ * 否则会使用{@link Lock4jProperties#getExpire() Lck4jProperties.expire}指定的过期时间。
+ *
+ *
注意:过期时间请务必保证长于业务的执行时间,未在配置文件中指定超时时间时,则默认为30s。 + * + * @return 锁的过期时间 + * @see LockExecutor#supportRenewal() + * @see #autoRelease() */ - boolean autoRelease() default true; + long expire() default -1; /** - * 失败策略 + *
在方法执行完后是否自动释放锁, + * 当设置为{@code false}时,锁将不会自动释放,直至到达过期时间才会释放。 * - * @return LockFailureStrategy + * @return 是否自动释放锁 */ - Class extends LockFailureStrategy> failStrategy() default LockFailureStrategy.class; + boolean autoRelease() default true; /** - * key生成器策略 + *
要使用的{@link LockFailureStrategy 当获取锁失败时的处理策略}类型, + * 默认优先使用{@link Lock4jProperties#getPrimaryFailureStrategy()} Lck4jProperties.primaryFailureStrategy}所指定的执行器。 * - * @return LockKeyBuilder + * @return 失败策略类型 + * @see LockFailureStrategy */ - Class extends LockKeyBuilder> keyBuilderStrategy() default LockKeyBuilder.class; + Class extends LockFailureStrategy> failStrategy() default LockFailureStrategy.class; /** - * 获取顺序,值越小越先执行 + *
当存在多个{@link Lock4j}注解时, + * 将会根据该值进行排序,顺序值越小越先执行。 * * @return 顺序值 */ int order() default Ordered.LOWEST_PRECEDENCE; + /** + * 多级注解 + * + * @author huangchengxing + */ @Target(value = {ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(value = RetentionPolicy.RUNTIME) @Inherited diff --git a/lock4j-core/src/main/java/com/baomidou/lock/annotation/LockWithDefault.java b/lock4j-core/src/main/java/com/baomidou/lock/annotation/LockWithDefault.java index 3ea368e..6ddacdb 100644 --- a/lock4j-core/src/main/java/com/baomidou/lock/annotation/LockWithDefault.java +++ b/lock4j-core/src/main/java/com/baomidou/lock/annotation/LockWithDefault.java @@ -27,63 +27,108 @@ import java.lang.annotation.*; public @interface LockWithDefault { /** - * 应用条件表达式,当执行结果为{@code true}或{@code 'true'}时,才会执行锁操作 + *
应用条件表达式,当执行结果为{@code true}或{@code 'true'}时,才会执行锁操作。 * - * @return 名称 + *
你可以在表达式中引用上下文参数: + *
key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面, + * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。 * - * @return 名称 + * @return key前缀 */ + @AliasFor("name") + String prefix() default ""; + + /** + *
key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面, + * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。 + * + * @return key前缀 + */ + @AliasFor("prefix") String name() default ""; /** - * @return lock 执行器 + *
要使用的{@link LockExecutor 锁执行器}类型, + * 默认优先使用{@link Lock4jProperties#getPrimaryExecutor() Lck4jProperties.primaryExecutor}所指定的执行器, + * + * @return 执行器类型 + * @see LockExecutor */ Class extends LockExecutor> executor() default LockExecutor.class; /** - * support SPEL expresion 锁的key = name + keys + * 要用于加锁的key,执行时, + * 将通过{@link #keyBuilderStrategy()}指定的策略生成最终的key。 * - * @return KEY + * @return 要加锁的key + * @see #keyBuilderStrategy() + * @see LockKeyBuilder */ String[] keys() default ""; /** - * @return 过期时间 单位:毫秒 - *
- * 过期时间一定是要长于业务的执行时间. 未设置则为默认时间30秒 默认值:{@link Lock4jProperties#expire} - *+ *
要使用的{@link LockKeyBuilder key生成器}类型, + * 默认优先使用{@link DefaultLockKeyBuilder}。 + * + * @return 生成器类型 */ - long expire() default -1; + Class extends LockKeyBuilder> keyBuilderStrategy() default DefaultLockKeyBuilder.class; /** - * @return 获取锁超时时间 单位:毫秒 - *
- * 结合业务,建议该时间不宜设置过长,特别在并发高的情况下. 未设置则为默认时间3秒 默认值:{@link Lock4jProperties#acquireTimeout} - *+ *
获取锁超时时间,单位为毫秒。 + *
注意:并发较高的情况下该值不易设置过大,请结合业务设置一个合理的等待时间。 + * + * @return 获取锁超时时间 */ long acquireTimeout() default -1; /** - * 业务方法执行完后(方法内抛异常也算执行完)自动释放锁,如果为false,锁将不会自动释放直至到达过期时间才释放 {@link com.baomidou.lock.annotation.Lock4j#expire()} + *
锁的过期时间,单位为毫秒。 * - * @return 是否自动释放锁 + *
当该值小于等于0时,若所使用的{@link #executor() 执行器}支持自动续期,
+ * 则在业务执行期间将会自动续期,直至业务执行完毕后才会释放锁。
+ * 否则会使用{@link Lock4jProperties#getExpire() Lck4jProperties.expire}指定的过期时间。
+ *
+ *
注意:过期时间请务必保证长于业务的执行时间,未在配置文件中指定超时时间时,则默认为30s。 + * + * @return 锁的过期时间 + * @see LockExecutor#supportRenewal() + * @see #autoRelease() */ - boolean autoRelease() default true; + long expire() default -1; /** - * key生成器策略,默认使用{@link DefaultLockKeyBuilder} + *
在方法执行完后是否自动释放锁, + * 当设置为{@code false}时,锁将不会自动释放,直至到达过期时间才会释放。 * - * @return LockKeyBuilder + * @return 是否自动释放锁 */ - Class extends LockKeyBuilder> keyBuilderStrategy() default DefaultLockKeyBuilder.class; + boolean autoRelease() default true; /** - * 获取顺序,值越小越先执行 + *
当存在多个{@link Lock4j}注解时,
+ * 将会根据该值进行排序,顺序值越小越先执行。
*
* @return 顺序值
*/
diff --git a/lock4j-core/src/main/java/com/baomidou/lock/aop/LockOpsInterceptor.java b/lock4j-core/src/main/java/com/baomidou/lock/aop/LockOpsInterceptor.java
index f26e027..e8d9e7e 100644
--- a/lock4j-core/src/main/java/com/baomidou/lock/aop/LockOpsInterceptor.java
+++ b/lock4j-core/src/main/java/com/baomidou/lock/aop/LockOpsInterceptor.java
@@ -105,6 +105,7 @@ public class LockOpsInterceptor extends AbstractConditionalLockChainInterceptor
String prefix = lock4jProperties.getLockKeyPrefix() + ":";
Method method = invocation.getMethod();
Lock4j annotation = lockOps.getAnnotation();
+ // FIXME 此处无法区分重载的方法,应直接替换为method.toString()
prefix += StringUtils.hasText(annotation.name()) ? annotation.name() :
method.getDeclaringClass().getName() + method.getName();
String key = prefix + "#" + lockOps.getLockKeyBuilder().buildKey(invocation, annotation.keys());
diff --git a/lock4j-core/src/main/java/com/baomidou/lock/executor/LocalLockExecutor.java b/lock4j-core/src/main/java/com/baomidou/lock/executor/LocalLockExecutor.java
index c64660c..c074278 100644
--- a/lock4j-core/src/main/java/com/baomidou/lock/executor/LocalLockExecutor.java
+++ b/lock4j-core/src/main/java/com/baomidou/lock/executor/LocalLockExecutor.java
@@ -4,6 +4,7 @@ import com.baomidou.lock.exception.LockException;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.lang.Nullable;
import org.springframework.util.ConcurrentReferenceHashMap;
import java.util.Objects;
@@ -57,6 +58,7 @@ public class LocalLockExecutor extends AbstractLockExecutor 应用条件表达式,当执行结果为{@code true}或{@code 'true'}时,才会执行锁操作。
*
- * @return 名称
+ * 你可以在表达式中引用上下文参数:
+ * key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面,
+ * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。
+ *
+ * @return key前缀
+ */
+ @AliasFor("name")
+ String prefix() default "";
+
+ /**
+ * key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面,
+ * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。
*
- * @return 名称
+ * @return key前缀
*/
+ @AliasFor("prefix")
String name() default "";
/**
- * support SPEL expresion 锁的key = name + keys
+ * 要用于加锁的key,执行时,
+ * 将通过{@link #keyBuilderStrategy()}指定的策略生成最终的key。
*
- * @return KEY
+ * @return 要加锁的key
+ * @see #keyBuilderStrategy()
+ * @see LockKeyBuilder
*/
String[] keys() default "";
/**
- * @return 过期时间 单位:毫秒
- * 要使用的{@link LockKeyBuilder key生成器}类型,
+ * 默认优先使用{@link Lock4jProperties#getPrimaryKeyBuilder()} Lck4jProperties.primaryKeyBuilder}所指定的执行器。
+ *
+ * @return 生成器类型
+ * @see LockKeyBuilder
*/
- long expire() default -1;
+ Class extends LockKeyBuilder> keyBuilderStrategy() default LockKeyBuilder.class;
/**
- * @return 获取锁超时时间 单位:毫秒
- * 获取锁超时时间,单位为毫秒。
+ * 注意:并发较高的情况下该值不易设置过大,请结合业务设置一个合理的等待时间。
+ *
+ * @return 获取锁超时时间
+ * @see #failStrategy()
*/
long acquireTimeout() default -1;
/**
- * 业务方法执行完后(方法内抛异常也算执行完)自动释放锁,如果为false,锁将不会自动释放直至到达过期时间才释放 {@link com.baomidou.lock.annotation.Lock4j#expire()}
+ * 锁的过期时间,单位为毫秒。
*
- * @return 是否自动释放锁
+ * 当该值小于等于0时,若所使用的{@link #executor() 执行器}支持自动续期,
+ * 则在业务执行期间将会自动续期,直至业务执行完毕后才会释放锁。 注意:过期时间请务必保证长于业务的执行时间,未在配置文件中指定超时时间时,则默认为30s。
+ *
+ * @return 锁的过期时间
+ * @see LockExecutor#supportRenewal()
+ * @see #autoRelease()
*/
- boolean autoRelease() default true;
+ long expire() default -1;
/**
- * 失败策略
+ * 在方法执行完后是否自动释放锁,
+ * 当设置为{@code false}时,锁将不会自动释放,直至到达过期时间才会释放。
*
- * @return LockFailureStrategy
+ * @return 是否自动释放锁
*/
- Class extends LockFailureStrategy> failStrategy() default LockFailureStrategy.class;
+ boolean autoRelease() default true;
/**
- * key生成器策略
+ * 要使用的{@link LockFailureStrategy 当获取锁失败时的处理策略}类型,
+ * 默认优先使用{@link Lock4jProperties#getPrimaryFailureStrategy()} Lck4jProperties.primaryFailureStrategy}所指定的执行器。
*
- * @return LockKeyBuilder
+ * @return 失败策略类型
+ * @see LockFailureStrategy
*/
- Class extends LockKeyBuilder> keyBuilderStrategy() default LockKeyBuilder.class;
+ Class extends LockFailureStrategy> failStrategy() default LockFailureStrategy.class;
/**
- * 获取顺序,值越小越先执行
+ * 当存在多个{@link Lock4j}注解时,
+ * 将会根据该值进行排序,顺序值越小越先执行。
*
* @return 顺序值
*/
diff --git a/lock4j-redis-template-spring-boot-starter/src/main/java/com/baomidou/lock/executor/RedisTemplateLockExecutor.java b/lock4j-redis-template-spring-boot-starter/src/main/java/com/baomidou/lock/executor/RedisTemplateLockExecutor.java
index 25a6c52..b1d9b02 100644
--- a/lock4j-redis-template-spring-boot-starter/src/main/java/com/baomidou/lock/executor/RedisTemplateLockExecutor.java
+++ b/lock4j-redis-template-spring-boot-starter/src/main/java/com/baomidou/lock/executor/RedisTemplateLockExecutor.java
@@ -23,6 +23,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
+import org.springframework.lang.Nullable;
import java.util.Collections;
import java.util.Timer;
@@ -50,10 +51,11 @@ public class RedisTemplateLockExecutor extends AbstractLockExecutor 应用条件表达式,当执行结果为{@code true}或{@code 'true'}时,才会执行锁操作。
*
- * @return 名称
+ * 你可以在表达式中引用上下文参数:
+ * key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面,
+ * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。
+ *
+ * @return key前缀
+ */
+ @AliasFor("name")
+ String prefix() default "";
+
+ /**
+ * key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面,
+ * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。
*
- * @return 名称
+ * @return key前缀
*/
+ @AliasFor("prefix")
String name() default "";
/**
- * support SPEL expresion 锁的key = name + keys
+ * 要用于加锁的key,执行时,
+ * 将通过{@link #keyBuilderStrategy()}指定的策略生成最终的key。
*
- * @return KEY
+ * @return 要加锁的key
+ * @see #keyBuilderStrategy()
+ * @see LockKeyBuilder
*/
String[] keys() default "";
/**
- * @return 过期时间 单位:毫秒
- * 要使用的{@link LockKeyBuilder key生成器}类型,
+ * 默认优先使用{@link Lock4jProperties#getPrimaryKeyBuilder()} Lck4jProperties.primaryKeyBuilder}所指定的执行器。
+ *
+ * @return 生成器类型
+ * @see LockKeyBuilder
*/
- long expire() default -1;
+ Class extends LockKeyBuilder> keyBuilderStrategy() default LockKeyBuilder.class;
/**
- * @return 获取锁超时时间 单位:毫秒
- * 获取锁超时时间,单位为毫秒。
+ * 注意:并发较高的情况下该值不易设置过大,请结合业务设置一个合理的等待时间。
+ *
+ * @return 获取锁超时时间
+ * @see #failStrategy()
*/
long acquireTimeout() default -1;
/**
- * 业务方法执行完后(方法内抛异常也算执行完)自动释放锁,如果为false,锁将不会自动释放直至到达过期时间才释放 {@link com.baomidou.lock.annotation.Lock4j#expire()}
+ * 锁的过期时间,单位为毫秒。
*
- * @return 是否自动释放锁
+ * 当该值小于等于0时,若所使用的{@link #executor() 执行器}支持自动续期,
+ * 则在业务执行期间将会自动续期,直至业务执行完毕后才会释放锁。 注意:过期时间请务必保证长于业务的执行时间,未在配置文件中指定超时时间时,则默认为30s。
+ *
+ * @return 锁的过期时间
+ * @see LockExecutor#supportRenewal()
+ * @see #autoRelease()
*/
- boolean autoRelease() default true;
+ long expire() default -1;
/**
- * 失败策略
+ * 在方法执行完后是否自动释放锁,
+ * 当设置为{@code false}时,锁将不会自动释放,直至到达过期时间才会释放。
*
- * @return LockFailureStrategy
+ * @return 是否自动释放锁
*/
- Class extends LockFailureStrategy> failStrategy() default LockFailureStrategy.class;
+ boolean autoRelease() default true;
/**
- * key生成器策略
+ * 要使用的{@link LockFailureStrategy 当获取锁失败时的处理策略}类型,
+ * 默认优先使用{@link Lock4jProperties#getPrimaryFailureStrategy()} Lck4jProperties.primaryFailureStrategy}所指定的执行器。
*
- * @return LockKeyBuilder
+ * @return 失败策略类型
+ * @see LockFailureStrategy
*/
- Class extends LockKeyBuilder> keyBuilderStrategy() default LockKeyBuilder.class;
+ Class extends LockFailureStrategy> failStrategy() default LockFailureStrategy.class;
/**
- * 获取顺序,值越小越先执行
+ * 当存在多个{@link Lock4j}注解时,
+ * 将会根据该值进行排序,顺序值越小越先执行。
*
* @return 顺序值
*/
diff --git a/lock4j-redisson-spring-boot-starter/src/main/java/com/baomidou/lock/executor/RedissonLockExecutor.java b/lock4j-redisson-spring-boot-starter/src/main/java/com/baomidou/lock/executor/RedissonLockExecutor.java
index b7453cd..8e48328 100644
--- a/lock4j-redisson-spring-boot-starter/src/main/java/com/baomidou/lock/executor/RedissonLockExecutor.java
+++ b/lock4j-redisson-spring-boot-starter/src/main/java/com/baomidou/lock/executor/RedissonLockExecutor.java
@@ -20,6 +20,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
+import org.springframework.lang.Nullable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@@ -36,10 +37,11 @@ public class RedissonLockExecutor extends AbstractLockExecutor 应用条件表达式,当执行结果为{@code true}或{@code 'true'}时,才会执行锁操作。
*
- * @return 名称
+ * 你可以在表达式中引用上下文参数:
+ * key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面,
+ * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。
+ *
+ * @return key前缀
+ */
+ @AliasFor("name")
+ String prefix() default "";
+
+ /**
+ * key前缀,它将会被拼接到根据{@link #keys()}属性生成的key前面,
+ * 当为空时,默认为当前加锁方法的{@code "声明类全限定名#方法名称"}。
*
- * @return 名称
+ * @return key前缀
*/
+ @AliasFor("prefix")
String name() default "";
/**
- * support SPEL expresion 锁的key = name + keys
+ * 要使用的{@link LockExecutor 锁执行器}类型,
+ * 默认优先使用{@link Lock4jProperties#getPrimaryExecutor() Lck4jProperties.primaryExecutor}所指定的执行器,
+ *
+ * @return 执行器类型
+ * @see LockExecutor
+ */
+ Class extends LockExecutor> executor() default LockExecutor.class;
+
+ /**
+ * 要用于加锁的key,执行时,
+ * 将通过{@link #keyBuilderStrategy()}指定的策略生成最终的key。
*
- * @return KEY
+ * @return 要加锁的key
+ * @see #keyBuilderStrategy()
+ * @see LockKeyBuilder
*/
String[] keys() default "";
/**
- * @return 过期时间 单位:毫秒
- * 要使用的{@link LockKeyBuilder key生成器}类型,
+ * 默认优先使用{@link Lock4jProperties#getPrimaryKeyBuilder()} Lck4jProperties.primaryKeyBuilder}所指定的执行器。
+ *
+ * @return 生成器类型
+ * @see LockKeyBuilder
*/
- long expire() default -1;
+ Class extends LockKeyBuilder> keyBuilderStrategy() default LockKeyBuilder.class;
/**
- * @return 获取锁超时时间 单位:毫秒
- * 获取锁超时时间,单位为毫秒。
+ * 注意:并发较高的情况下该值不易设置过大,请结合业务设置一个合理的等待时间。
+ *
+ * @return 获取锁超时时间
+ * @see #failStrategy()
*/
long acquireTimeout() default -1;
/**
- * 业务方法执行完后(方法内抛异常也算执行完)自动释放锁,如果为false,锁将不会自动释放直至到达过期时间才释放 {@link com.baomidou.lock.annotation.Lock4j#expire()}
+ * 锁的过期时间,单位为毫秒。
*
- * @return 是否自动释放锁
+ * 当该值小于等于0时,若所使用的{@link #executor() 执行器}支持自动续期,
+ * 则在业务执行期间将会自动续期,直至业务执行完毕后才会释放锁。 注意:过期时间请务必保证长于业务的执行时间,未在配置文件中指定超时时间时,则默认为30s。
+ *
+ * @return 锁的过期时间
+ * @see LockExecutor#supportRenewal()
+ * @see #autoRelease()
*/
- boolean autoRelease() default true;
+ long expire() default -1;
/**
- * 失败策略
+ * 在方法执行完后是否自动释放锁,
+ * 当设置为{@code false}时,锁将不会自动释放,直至到达过期时间才会释放。
*
- * @return LockFailureStrategy
+ * @return 是否自动释放锁
*/
- Class extends LockFailureStrategy> failStrategy() default LockFailureStrategy.class;
+ boolean autoRelease() default true;
/**
- * key生成器策略
+ * 要使用的{@link LockFailureStrategy 当获取锁失败时的处理策略}类型,
+ * 默认优先使用{@link Lock4jProperties#getPrimaryFailureStrategy()} Lck4jProperties.primaryFailureStrategy}所指定的执行器。
*
- * @return LockKeyBuilder
+ * @return 失败策略类型
+ * @see LockFailureStrategy
*/
- Class extends LockKeyBuilder> keyBuilderStrategy() default LockKeyBuilder.class;
+ Class extends LockFailureStrategy> failStrategy() default LockFailureStrategy.class;
/**
- * 获取顺序,值越小越先执行
+ * 当存在多个{@link Lock4j}注解时,
+ * 将会根据该值进行排序,顺序值越小越先执行。
*
* @return 顺序值
*/
diff --git a/lock4j-zookeeper-spring-boot-starter/src/main/java/com/baomidou/lock/executor/ZookeeperLockExecutor.java b/lock4j-zookeeper-spring-boot-starter/src/main/java/com/baomidou/lock/executor/ZookeeperLockExecutor.java
index 200170e..427995c 100644
--- a/lock4j-zookeeper-spring-boot-starter/src/main/java/com/baomidou/lock/executor/ZookeeperLockExecutor.java
+++ b/lock4j-zookeeper-spring-boot-starter/src/main/java/com/baomidou/lock/executor/ZookeeperLockExecutor.java
@@ -21,6 +21,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.imps.CuratorFrameworkState;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
+import org.springframework.lang.Nullable;
import java.util.concurrent.TimeUnit;
@@ -35,6 +36,7 @@ public class ZookeeperLockExecutor extends AbstractLockExecutor
+ *
+ * 并且,与{@link org.springframework.beans.factory.annotation.Value @Value}注解一样,
+ * 支持通过{@code "${}"}引用配置文件中的属性。
+ *
+ * @return 条件表达式
+ * @see com.baomidou.lock.MethodBasedExpressionEvaluator
+ * @see com.baomidou.lock.aop.AbstractConditionalLockInterceptor
*/
String condition() default "";
/**
- * 用于多个方法锁同一把锁 可以理解为锁资源名称 为空则会使用 包名+类名+方法名
+ *
- * 过期时间一定是要长于业务的执行时间. 未设置则为默认时间30秒 默认值:{@link Lock4jProperties#expire}
- *
+ *
- * 结合业务,建议该时间不宜设置过长,特别在并发高的情况下. 未设置则为默认时间3秒 默认值:{@link Lock4jProperties#acquireTimeout}
- *
+ *
+ *
+ * 当获取锁失败时,将会根据{@link #failStrategy()}指定的策略进行处理。
+ *
+ *
+ * 否则会使用{@link Lock4jProperties#getExpire() Lck4jProperties.expire}指定的过期时间。
+ *
+ *
+ *
+ * 并且,与{@link org.springframework.beans.factory.annotation.Value @Value}注解一样,
+ * 支持通过{@code "${}"}引用配置文件中的属性。
+ *
+ * @return 条件表达式
+ * @see com.baomidou.lock.MethodBasedExpressionEvaluator
+ * @see com.baomidou.lock.aop.AbstractConditionalLockInterceptor
*/
String condition() default "";
/**
- * 用于多个方法锁同一把锁 可以理解为锁资源名称 为空则会使用 包名+类名+方法名
+ *
- * 过期时间一定是要长于业务的执行时间. 未设置则为默认时间30秒 默认值:{@link Lock4jProperties#expire}
- *
+ *
- * 结合业务,建议该时间不宜设置过长,特别在并发高的情况下. 未设置则为默认时间3秒 默认值:{@link Lock4jProperties#acquireTimeout}
- *
+ *
+ *
+ * 当获取锁失败时,将会根据{@link #failStrategy()}指定的策略进行处理。
+ *
+ *
+ * 否则会使用{@link Lock4jProperties#getExpire() Lck4jProperties.expire}指定的过期时间。
+ *
+ *
+ *
+ * 并且,与{@link org.springframework.beans.factory.annotation.Value @Value}注解一样,
+ * 支持通过{@code "${}"}引用配置文件中的属性。
+ *
+ * @return 条件表达式
+ * @see com.baomidou.lock.MethodBasedExpressionEvaluator
+ * @see com.baomidou.lock.aop.AbstractConditionalLockInterceptor
*/
String condition() default "";
/**
- * 用于多个方法锁同一把锁 可以理解为锁资源名称 为空则会使用 包名+类名+方法名
+ *
- * 过期时间一定是要长于业务的执行时间. 未设置则为默认时间30秒 默认值:{@link Lock4jProperties#expire}
- *
+ *
- * 结合业务,建议该时间不宜设置过长,特别在并发高的情况下. 未设置则为默认时间3秒 默认值:{@link Lock4jProperties#acquireTimeout}
- *
+ *
+ *
+ * 当获取锁失败时,将会根据{@link #failStrategy()}指定的策略进行处理。
+ *
+ *
+ * 否则会使用{@link Lock4jProperties#getExpire() Lck4jProperties.expire}指定的过期时间。
+ *
+ *