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

shz.spring.lock.LockAdvisor Maven / Gradle / Ivy

There is a newer version: 2023.2.5
Show newest version
package shz.spring.lock;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import shz.core.KeyBuilder;
import shz.core.PRException;
import shz.core.lock.Lock;
import shz.core.lock.LockKey;
import shz.core.lock.LockManager;
import shz.core.lock.Locker;
import shz.core.lock.ReadWriteLockManager;
import shz.core.lock.ReentrantLockManager;
import shz.core.lock.StampedLockManager;
import shz.spring.BeanContainer;

import java.lang.reflect.Method;
import java.util.Objects;
import java.util.function.Supplier;

public final class LockAdvisor extends DefaultPointcutAdvisor {
    private static final long serialVersionUID = -6557058814035302519L;

    public LockAdvisor() {
        setPointcut(pointcut());
        setAdvice(advice());
    }

    private Pointcut pointcut() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("@annotation(shz.core.lock.Lock)");
        return pointcut;
    }

    private Advice advice() {
        return (MethodInterceptor) invocation -> {
            Method method = invocation.getMethod();
            Lock lock = method.getAnnotation(Lock.class);
            if (lock == null) return invocation.proceed();

            LockManager manager;
            if (lock.manager() == ReentrantLockManager.class) manager = ReentrantLockManager.INSTANCE;
            else if (lock.manager() == ReadWriteLockManager.class) manager = ReadWriteLockManager.INSTANCE;
            else if (lock.manager() == StampedLockManager.class) manager = StampedLockManager.INSTANCE;
            else {
                manager = BeanContainer.get(lock.manager());
                Objects.requireNonNull(manager);
            }

            Supplier supplier = () -> {
                try {
                    return invocation.proceed();
                } catch (Throwable t) {
                    throw PRException.of(t);
                }
            };

            String lockKey = KeyBuilder.generateKey(lock.value(), method, invocation.getArguments(), LockKey.class, LockKey::value);
            return Locker.apply(lock.readOnly(), manager, supplier, lock.time(), lock.unit(), lockKey);
        };
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy