java自定义注解运用

2022/2/8 14:13:12

本文主要是介绍java自定义注解运用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

java自定义注解运用

下面是用redis编写自定义注解实现进程锁:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.hr360.redission.lock.aop.annonation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface UseRLock {
    long maxLockTime() default 5000L;

    String area() default "default";

    String clazz() default "default";

    String method() default "default";

    UseRLock.LockPolicy policy() default UseRLock.LockPolicy.REJECT;

    public static enum LockPolicy {
        WAIT,
        REJECT;

        private LockPolicy() {
        }
    }
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.hr360.redission.lock.aop.annonation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface LockKey {
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.hr360.redission.lock.aop;

public class RLockException extends RuntimeException {
    public RLockException(String message) {
        super(message);
    }
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.hr360.redission.lock.aop;

import com.hr360.commons.exception.hr360Exception;
import com.hr360.redission.lock.aop.annonation.LockKey;
import com.hr360.redission.lock.aop.annonation.UseRLock;
import com.hr360.redission.lock.aop.annonation.UseRLock.LockPolicy;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.concurrent.TimeUnit;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.StringUtils;

@Aspect
@Component
public class UseRLockAspect {
    private static final String REDIS_NS = "rlock:";
    private static final String DEFAULT = "default";
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private RedissonClient redissonClient;

    public UseRLockAspect() {
    }

    @AfterThrowing(
        value = "@annotation(com.hr360.redission.lock.aop.annonation.UseRLock)",
        throwing = "e"
    )
    public void afterThrowing(final JoinPoint joinPoint, Exception e) throws Throwable {
        if (!TransactionSynchronizationManager.isSynchronizationActive()) {
            this.unlock(joinPoint);
        } else {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                public void afterCompletion(int status) {
                    try {
                        UseRLockAspect.this.unlock(joinPoint);
                    } catch (NoSuchMethodException var3) {
                        UseRLockAspect.this.log.error("unlock:{}", var3);
                    }

                }
            });
        }

    }

    @AfterReturning("@annotation(com.hr360.redission.lock.aop.annonation.UseRLock)")
    public void after(final JoinPoint joinPoint) throws Throwable {
        if (!TransactionSynchronizationManager.isSynchronizationActive()) {
            this.unlock(joinPoint);
        } else {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                public void afterCommit() {
                    try {
                        UseRLockAspect.this.unlock(joinPoint);
                    } catch (NoSuchMethodException var2) {
                        UseRLockAspect.this.log.error("unlock:{}", var2);
                    }

                }
            });
        }

    }

    private void unlock(JoinPoint joinPoint) throws NoSuchMethodException {
        UseRLock annotation = this.getUseRLock(joinPoint);
        String lockKey = this.getLockKey(annotation.area(), annotation.clazz(), annotation.method(), joinPoint);
        RLock lock = this.redissonClient.getLock(lockKey);
        if (lock != null && lock.isHeldByCurrentThread() && lock.isLocked()) {
            lock.unlock();
        }

    }

    @Around("@annotation(com.hr360.redission.lock.aop.annonation.UseRLock)")
    public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
        this.lock(pjp);
        return pjp.proceed();
    }

    private void lock(ProceedingJoinPoint pjp) throws NoSuchMethodException {
        UseRLock annotation = this.getUseRLock(pjp);
        long maxLockTime = annotation.maxLockTime();
        String area = annotation.area();
        String clazz = annotation.clazz();
        String method = annotation.method();
        LockPolicy policy = annotation.policy();
        RLock lock = null;
        String lockKey = this.getLockKey(area, clazz, method, pjp);
        lock = this.redissonClient.getLock(lockKey);
        boolean locked = lock.isLocked();
        if (locked && LockPolicy.REJECT.equals(policy)) {
            throw new hr360Exception((String)null, "此业务调用仅允许一个并发处理");
        } else {
            lock.lock(maxLockTime, TimeUnit.MILLISECONDS);
        }
    }

    private UseRLock getUseRLock(JoinPoint pjp) throws NoSuchMethodException {
        Signature signature = pjp.getSignature();
        MethodSignature mSignature = (MethodSignature)signature;
        Class<?> declaringType = mSignature.getDeclaringType();
        Method method = declaringType.getDeclaredMethod(mSignature.getName(), mSignature.getParameterTypes());
        return (UseRLock)method.getAnnotation(UseRLock.class);
    }

    private String getLockKey(String area, String clazz, String methodName, JoinPoint pjp) throws NoSuchMethodException {
        Signature signature = pjp.getSignature();
        MethodSignature mSignature = (MethodSignature)signature;
        Class<?> declaringType = mSignature.getDeclaringType();
        Method method = declaringType.getDeclaredMethod(mSignature.getName(), mSignature.getParameterTypes());
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        if (parameterAnnotations != null && parameterAnnotations.length != 0) {
            if ("default".equals(clazz)) {
                clazz = declaringType.getName();
            }

            if ("default".equals(methodName)) {
                methodName = method.getName();
            }

            Parameter[] parameters = method.getParameters();
            Object[] args = pjp.getArgs();
            StringBuilder lockKey = new StringBuilder();
            lockKey.append("rlock:");
            lockKey.append(area);
            lockKey.append(":");
            lockKey.append(clazz);
            lockKey.append(":");
            lockKey.append(methodName);
            lockKey.append(":");
            boolean hasLockKey = false;

            for(int index = 0; index < args.length; ++index) {
                Parameter parameter = parameters[index];
                LockKey annotation = (LockKey)parameter.getAnnotation(LockKey.class);
                if (annotation != null) {
                    Object arg = args[index];
                    String argStr = arg.toString();
                    if (arg == null || StringUtils.isEmpty(argStr)) {
                        throw new RLockException("@LockKey parameter must not be null");
                    }

                    hasLockKey = true;
                    lockKey.append(argStr);
                }
            }

            if (!hasLockKey) {
                throw new RLockException("@LockKey must be assigned");
            } else {
                return lockKey.toString();
            }
        } else {
            throw new RLockException("@LockKey must be assigned");
        }
    }
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.hr360.redisson.autoconfigure;

import java.time.Duration;
import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(
    prefix = "hr360.redission.redis"
)
public class RedissionProperties {
    private int database = 0;
    private String url;
    private String host = "localhost";
    private String password;
    private int port = 6379;
    private boolean ssl;
    private Duration timeout;
    private RedissionProperties.Sentinel sentinel;
    private RedissionProperties.Cluster cluster;
    private final RedissionProperties.Jedis jedis = new RedissionProperties.Jedis();
    private final RedissionProperties.Lettuce lettuce = new RedissionProperties.Lettuce();

    public RedissionProperties() {
    }

    public int getDatabase() {
        return this.database;
    }

    public void setDatabase(int database) {
        this.database = database;
    }

    public String getUrl() {
        return this.url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getHost() {
        return this.host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getPort() {
        return this.port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public boolean isSsl() {
        return this.ssl;
    }

    public void setSsl(boolean ssl) {
        this.ssl = ssl;
    }

    public void setTimeout(Duration timeout) {
        this.timeout = timeout;
    }

    public Duration getTimeout() {
        return this.timeout;
    }

    public RedissionProperties.Sentinel getSentinel() {
        return this.sentinel;
    }

    public void setSentinel(RedissionProperties.Sentinel sentinel) {
        this.sentinel = sentinel;
    }

    public RedissionProperties.Cluster getCluster() {
        return this.cluster;
    }

    public void setCluster(RedissionProperties.Cluster cluster) {
        this.cluster = cluster;
    }

    public RedissionProperties.Jedis getJedis() {
        return this.jedis;
    }

    public RedissionProperties.Lettuce getLettuce() {
        return this.lettuce;
    }

    public static class Pool {
        private int maxIdle = 8;
        private int minIdle = 0;
        private int maxActive = 8;
        private Duration maxWait = Duration.ofMillis(-1L);

        public Pool() {
        }

        public int getMaxIdle() {
            return this.maxIdle;
        }

        public void setMaxIdle(int maxIdle) {
            this.maxIdle = maxIdle;
        }

        public int getMinIdle() {
            return this.minIdle;
        }

        public void setMinIdle(int minIdle) {
            this.minIdle = minIdle;
        }

        public int getMaxActive() {
            return this.maxActive;
        }

        public void setMaxActive(int maxActive) {
            this.maxActive = maxActive;
        }

        public Duration getMaxWait() {
            return this.maxWait;
        }

        public void setMaxWait(Duration maxWait) {
            this.maxWait = maxWait;
        }
    }

    public static class Cluster {
        private List<String> nodes;
        private Integer maxRedirects;

        public Cluster() {
        }

        public List<String> getNodes() {
            return this.nodes;
        }

        public void setNodes(List<String> nodes) {
            this.nodes = nodes;
        }

        public Integer getMaxRedirects() {
            return this.maxRedirects;
        }

        public void setMaxRedirects(Integer maxRedirects) {
            this.maxRedirects = maxRedirects;
        }
    }

    public static class Sentinel {
        private String master;
        private List<String> nodes;

        public Sentinel() {
        }

        public String getMaster() {
            return this.master;
        }

        public void setMaster(String master) {
            this.master = master;
        }

        public List<String> getNodes() {
            return this.nodes;
        }

        public void setNodes(List<String> nodes) {
            this.nodes = nodes;
        }
    }

    public static class Jedis {
        private RedissionProperties.Pool pool;

        public Jedis() {
        }

        public RedissionProperties.Pool getPool() {
            return this.pool;
        }

        public void setPool(RedissionProperties.Pool pool) {
            this.pool = pool;
        }
    }

    public static class Lettuce {
        private Duration shutdownTimeout = Duration.ofMillis(100L);
        private RedissionProperties.Pool pool;

        public Lettuce() {
        }

        public Duration getShutdownTimeout() {
            return this.shutdownTimeout;
        }

        public void setShutdownTimeout(Duration shutdownTimeout) {
            this.shutdownTimeout = shutdownTimeout;
        }

        public RedissionProperties.Pool getPool() {
            return this.pool;
        }

        public void setPool(RedissionProperties.Pool pool) {
            this.pool = pool;
        }
    }
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.hr360.redisson.autoconfigure;

import com.hr360.redisson.autoconfigure.RedissionProperties.Sentinel;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.Config;
import org.redisson.config.SentinelServersConfig;
import org.redisson.config.SingleServerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.util.ReflectionUtils;

@Configuration
@EnableAspectJAutoProxy
@ComponentScan(
    basePackages = {"com.hr360.redission.lock.aop"}
)
@ConditionalOnClass({Redisson.class, RedisOperations.class})
@AutoConfigureBefore({RedisAutoConfiguration.class})
@EnableConfigurationProperties({RedissionProperties.class})
public class RedissonAutoConfiguration {
    private static final Logger log = LoggerFactory.getLogger(RedissonAutoConfiguration.class);
    @Autowired
    private RedissionProperties redissionProperties;

    public RedissonAutoConfiguration() {
        log.info("#### init RedissionAutoConfiguration success #### 20210306 Great");
    }

    @Bean(
        destroyMethod = "shutdown"
    )
    @ConditionalOnMissingBean({RedissonClient.class})
    public RedissonClient redisson() {
        Config config = null;
        Method clusterMethod = ReflectionUtils.findMethod(RedissionProperties.class, "getCluster");
        Method timeoutMethod = ReflectionUtils.findMethod(RedissionProperties.class, "getTimeout");
        Object timeoutValue = ReflectionUtils.invokeMethod(timeoutMethod, this.redissionProperties);
        int timeout;
        Method nodesMethod;
        if (null == timeoutValue) {
            timeout = 10000;
        } else if (!(timeoutValue instanceof Integer)) {
            nodesMethod = ReflectionUtils.findMethod(timeoutValue.getClass(), "toMillis");
            timeout = ((Long)ReflectionUtils.invokeMethod(nodesMethod, timeoutValue)).intValue();
        } else {
            timeout = (Integer)timeoutValue;
        }

        if (this.redissionProperties.getSentinel() != null) {
            nodesMethod = ReflectionUtils.findMethod(Sentinel.class, "getNodes");
            Object nodesValue = ReflectionUtils.invokeMethod(nodesMethod, this.redissionProperties.getSentinel());
            String[] nodes;
            if (nodesValue instanceof String) {
                nodes = this.convert(Arrays.asList(((String)nodesValue).split(",")));
            } else {
                nodes = this.convert((List)nodesValue);
            }

            config = new Config();
            ((SentinelServersConfig)config.useSentinelServers().setMasterName(this.redissionProperties.getSentinel().getMaster()).addSentinelAddress(nodes).setDatabase(this.redissionProperties.getDatabase()).setConnectTimeout(timeout)).setPassword(this.redissionProperties.getPassword());
        } else {
            Method method;
            if (clusterMethod != null && ReflectionUtils.invokeMethod(clusterMethod, this.redissionProperties) != null) {
                Object clusterObject = ReflectionUtils.invokeMethod(clusterMethod, this.redissionProperties);
                method = ReflectionUtils.findMethod(clusterObject.getClass(), "getNodes");
                List<String> nodesObject = (List)ReflectionUtils.invokeMethod(method, clusterObject);
                String[] nodes = this.convert(nodesObject);
                config = new Config();
                ((ClusterServersConfig)config.useClusterServers().addNodeAddress(nodes).setConnectTimeout(timeout)).setPassword(this.redissionProperties.getPassword());
            } else {
                config = new Config();
                String prefix = "redis://";
                method = ReflectionUtils.findMethod(RedissionProperties.class, "isSsl");
                if (method != null && (Boolean)ReflectionUtils.invokeMethod(method, this.redissionProperties)) {
                    prefix = "rediss://";
                }

                ((SingleServerConfig)((SingleServerConfig)config.useSingleServer().setAddress(prefix + this.redissionProperties.getHost() + ":" + this.redissionProperties.getPort()).setConnectTimeout(timeout)).setDatabase(this.redissionProperties.getDatabase()).setPassword(this.redissionProperties.getPassword())).setConnectionMinimumIdleSize(this.redissionProperties.getJedis().getPool().getMinIdle()).setConnectionPoolSize(this.redissionProperties.getJedis().getPool().getMaxActive());
            }
        }

        return Redisson.create(config);
    }

    private String[] convert(List<String> nodesObject) {
        List<String> nodes = new ArrayList(nodesObject.size());
        Iterator var3 = nodesObject.iterator();

        while(true) {
            while(var3.hasNext()) {
                String node = (String)var3.next();
                if (!node.startsWith("redis://") && !node.startsWith("rediss://")) {
                    nodes.add("redis://" + node);
                } else {
                    nodes.add(node);
                }
            }

            return (String[])nodes.toArray(new String[nodes.size()]);
        }
    }
}
<?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">
  
    <modelVersion>4.0.0</modelVersion>
    <artifactId>hr360-redisson-starter</artifactId>
    <packaging>jar</packaging>
    <version>2.8.221.fix</version>

    <properties>
        <org.redisson.version>3.12.4</org.redisson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator-autoconfigure</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson</artifactId>
            <version>4.0.0</version>
        </dependency>
        <!--<dependency>-->
            <!--<groupId>org.springframework</groupId>-->
            <!--<artifactId>spring-web</artifactId>-->
        <!--</dependency>-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.2</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>


这篇关于java自定义注解运用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程