All Downloads are FREE. Search and download functionalities are using the official Maven repository.

top.isopen.commons.springboot.lock.LockParameter Maven / Gradle / Ivy

There is a newer version: 1.2.8
Show newest version
package top.isopen.commons.springboot.lock;

import lombok.Value;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import top.isopen.commons.springboot.enums.BaseErrorEnum;
import top.isopen.commons.springboot.lock.annotation.RedLock;
import top.isopen.commons.springboot.lock.annotation.RedLocks;

import java.util.Arrays;
import java.util.concurrent.TimeUnit;

/**
 * 锁的参数
 * 

* 用来处理锁注解 {@link RedLock} {@link RedLocks} 中配置的锁参数 * * @author TimeChaser * @version 1.0 * @since 2023/7/7 17:41 */ @Value public class LockParameter { private static final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer(); private static final SpelExpressionParser spelExpressionParser = new SpelExpressionParser(); private static final String KEY_SEPARATOR = ":"; private static final char SP_EL_PREFIX = '#'; String key; String[] keys; String[] parameters; Object[] args; boolean fair; long leaseTime; TimeUnit timeUnit; long waitTime; LockParameter(RedLock redLock, JoinPoint joinPoint) { keys = null; parameters = parameterNameDiscoverer.getParameterNames(((MethodSignature) joinPoint.getSignature()).getMethod()); args = joinPoint.getArgs(); if (parameters != null && parameters.length != args.length) { BaseErrorEnum.INVALID_RED_LOCK_ASPECT_PARAMETER_ERROR.throwException(); } fair = redLock.isFair(); leaseTime = redLock.leaseTime(); timeUnit = redLock.timeUnit(); waitTime = redLock.waitTime(); key = resolveKey(redLock.key(), parameters, args); } LockParameter(RedLocks redLocks, JoinPoint joinPoint) { key = null; parameters = parameterNameDiscoverer.getParameterNames(((MethodSignature) joinPoint.getSignature()).getMethod()); args = joinPoint.getArgs(); if (parameters != null && parameters.length != args.length) { BaseErrorEnum.INVALID_RED_LOCK_ASPECT_PARAMETER_ERROR.throwException(); } fair = redLocks.isFair(); leaseTime = redLocks.leaseTime(); timeUnit = redLocks.timeUnit(); waitTime = redLocks.waitTime(); keys = resolveKey(redLocks.keys(), parameters, args); } /** * 解析 {@link RedLock#key()} * * @param key {@link RedLock#key()} * @param parameters 被 {@link RedLock} 注释的方法的参数项 * @param args 被 {@link RedLock} 注释的方法的参数值 * @return {@link String} * @author TimeChaser * @since 2023/8/25 14:48 */ private static String resolveKey(String key, String[] parameters, Object[] args) { StandardEvaluationContext context = getElContext(parameters, args); return resolveKey(key, context); } /** * 解析 {@link RedLocks#keys()} * * @param keys {@link RedLocks#keys()} * @param parameters 被 {@link RedLocks} 注释的方法的参数项 * @param args 被 {@link RedLocks} 注释的方法的参数值 * @return String[] * @author TimeChaser * @since 2023/8/25 14:50 */ private static String[] resolveKey(String[] keys, String[] parameters, Object[] args) { String[] values = new String[keys.length]; StandardEvaluationContext context = getElContext(parameters, args); for (int i = 0; i < keys.length; i++) { values[i] = resolveKey(keys[i], context); } return values; } /** * 通过 EL 表达式上下文解析 key *

* TODO 当前 {@link RedLock#key()} 中有且只能存在一个 EL 表达式,其实是可以通过递归和 try-catch 的组合优化的 * * @param key 锁的 key * @param context EL 上下文 * @return {@link String} * @author TimeChaser * @since 2023/8/25 14:51 */ private static String resolveKey(String key, StandardEvaluationContext context) { String[] comb = resolveEl(key); assert comb != null; assert comb.length == 3; String spEl = comb[1]; String value = spelExpressionParser.parseRaw(spEl).getValue(context, String.class); return (comb[0].length() != 0 ? comb[0] + KEY_SEPARATOR : "") + value + (comb[2].length() != 0 ? KEY_SEPARATOR + comb[2] : ""); } /** * 解析 key 的 EL 表达式组成部分 * * @param el EL 表达式 * @return String[] * @author TimeChaser * @since 2023/8/25 14:53 */ private static String[] resolveEl(String el) { String[] splits = el.split(KEY_SEPARATOR); for (int i = 0, n = splits.length; i < n; i++) { String target = splits[i]; if (target.charAt(0) == SP_EL_PREFIX) { return new String[]{ i == 0 ? "" : String.join("", Arrays.copyOfRange(splits, 0, i)), target, i == n - 1 ? "" : String.join("", Arrays.copyOfRange(splits, i + 1, n)) }; } } BaseErrorEnum.INVALID_SP_EL_ERROR.throwException(); return null; } /** * 组装 EL 表达式上下文 * * @param parameters 切面方法的参数项 * @param args 切面方法的参数值 * @return {@link StandardEvaluationContext} * @author TimeChaser * @since 2023/8/25 15:06 */ private static StandardEvaluationContext getElContext(String[] parameters, Object[] args) { StandardEvaluationContext context = new StandardEvaluationContext(); for (int i = 0; i < args.length; i++) { context.setVariable(parameters[i], args[i]); } return context; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy