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

cn.echo.distribution.lock.interceptor.DistributionLockInterceptor Maven / Gradle / Ivy

package cn.echo.distribution.lock.interceptor;

import cn.echo.distribution.lock.annotation.DistributionLock;
import cn.echo.distribution.lock.annotation.LockKey;
import cn.echo.distribution.lock.support.RedisLock;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.StringUtils;

import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.TreeMap;

public class DistributionLockInterceptor implements MethodInterceptor {
	
    RedisLock redisLock;

	private final static String PERIOD = ".";

	public void setRedisLock(RedisLock redisLock) {
		this.redisLock = redisLock;
	}

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		DistributionLock lockInfo = invocation.getMethod().getAnnotation(DistributionLock.class);
		if (lockInfo == null) {
			throw new IllegalArgumentException("DistributionLock argument illegal");
		}
		double idx = 0.1; //利用double特性实现key排序
		Object[] args = invocation.getArguments();
		Annotation[][] paramAnnotationArrays = invocation.getMethod().getParameterAnnotations();
		Map keys = new TreeMap<>();
		for (int ix = 0; ix < paramAnnotationArrays.length; ix++) {
			for (Annotation paramAnnotation : paramAnnotationArrays[ix]) {
				if (LockKey.class.equals(paramAnnotation.annotationType())) {
					LockKey lockKey = (LockKey) paramAnnotation;
					keys.put(keys.containsKey(0.0D + lockKey.index())? idx+lockKey.index(): lockKey.index(), ":" + args[ix]);
					idx += 0.1D;
					break;
				}
			}
		}
		String methodName = invocation.getMethod().getName();
		String lockName = StringUtils.isEmpty(lockInfo.value())? methodName: lockInfo.value();
		if (!keys.isEmpty()) {
			lockName += PERIOD + StringUtils.collectionToDelimitedString(keys.values(), ":");
		}
		long lockId = redisLock.lock(lockName, lockInfo.keepMills(), lockInfo.maxWaitMills(), methodName);
		try {
			return invocation.proceed();
		} finally {
			redisLock.unlock(lockName, lockId, methodName);
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy