1、导入依赖

<!--redisson 是一个用于Java的Redis客户端,可以方便地在Java应用程序中使用Redis
 AspectJ编织器,它可以用于实现AOP(面向切面编程)功能-->
<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.13.6</version>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.7</version>
</dependency>

2、redisson配置文件

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RedissonConfig {
    @Value("${spring.redis.host}")
    private String redisHost;

    @Value("${spring.redis.port}")
    private int redisPort;

    @Value("${spring.redis.database}")
    private int redisDatabase;

    /*redisson 不需要单独配置密码,指定好路径就行*/

    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        SingleServerConfig serverConfig = config.useSingleServer();
        serverConfig.setAddress("redis://" + redisHost + ":" + redisPort);
        serverConfig.setDatabase(redisDatabase);
        return Redisson.create(config);
    }
}

此处翻车了,遇到了一个问题是在yml文件中配置了redis的路径、端口、密码、库,到配置redisson时顺理成章的把这些都拿过来配置,导致报错说这个bean注册不成功,连接不上redis,!!!原因是:redisson连接时不需要密码,去掉就创建成功了(具体为什么我也不知道,可能是依赖关系)

3、编辑注解

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {
    String key();
    long leaseTime() default 30; // 默认锁定时间,单位:秒
    long waitTime() default 10;  // 默认等待时间,单位:秒
}

4、编辑增强逻辑

import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Aspect
@Component
@RequiredArgsConstructor
public class DistributedLockAspect {

    private final RedissonClient redissonClient;

    @Around("@annotation(distributedLock)")
    public Object around(ProceedingJoinPoint joinPoint, DistributedLock distributedLock) throws Throwable {
        String key = distributedLock.key();
        long leaseTime = distributedLock.leaseTime();
        long waitTime = distributedLock.waitTime();

        RLock lock = redissonClient.getLock(key);
        boolean acquired = false;

        try {
            acquired = lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
            if (acquired) {
                return joinPoint.proceed();
            } else {
                throw new RuntimeException("Could not acquire lock on key: " + key);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("Lock acquisition interrupted", e);
        } finally {
            if (acquired) {
                lock.unlock();
            }
        }
    }
}

5、启动类上增加注解

@EnableAspectJAutoProxy //启用了AspectJ自动代理

6、使用

在方法上使用注解就可以了

@DistributedLock(key = "materialCollection:lock:#datas[0].accountId", waitTime = 100, leaseTime = 10)

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐