基于注解的分布式锁

基于注解的分布式锁


在上一篇笔记中我们介绍了基于Redis的分布式锁,这一篇我们就介绍一下基于注解的方法去使用这个分布式锁,使用这种切面的方式可以有效的减少功能性代码对业务代码的侵入性。

本文中的RedisLockUtils链接

  • 首先我们需要定义一个注解类,相当于定义一个切点

    package com.example.demo.annotation;
    
    import java.lang.annotation.*;
    
    /**
     * @author : wulg29230
     * @Date : 2020/3/9 14:36
     **/
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RedisLock {
        /**
         * 入参的类型
         * @return
         */
        Class<?> type();
    
        /**
         * 入参中作为redis锁的key字段
         * @return
         */
        String key();
    
        /**
         * 获取锁等待时间
         * @return
         */
        long waitTime() default 0L;
    }
    
    
  • 然后我们写一个切面类,针对切点做业务处理

    package com.example.demo.aop;
    
    import com.example.demo.annotation.RedisLock;
    import com.example.demo.constant.BusinessExceptionEnum;
    import com.example.demo.exception.BusinessException;
    import com.example.demo.util.RedisLockUtils;
    import org.apache.dubbo.common.utils.StringUtils;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.stereotype.Component;
    
    
    import javax.annotation.Resource;
    import java.lang.reflect.Field;
    
    /**
     * @author : wulg29230
     * @Date : 2020/3/9 14:41
     **/
    @Component
    @Aspect
    public class RedisLockInterceptor {
    
        @Resource
        private RedisLockUtils redisLockUtils;
    
        @Around("@annotation(redisLock)")
        public Object around(ProceedingJoinPoint pjp, RedisLock redisLock) throws Throwable {
            //切点作用的方法的参数
            Object[] args = pjp.getArgs();
            String lockKey = null;
            boolean flag = false;
            for(Object object : args) {
                //判断入参中是否有需要锁的对象
                if(object.getClass().equals(redisLock.type())) {
                    Field[] fields = object.getClass().getDeclaredFields();
                    for(Field field : fields){
                        field.setAccessible(true);
                        if(redisLock.key().equals(field.getName())){
                            lockKey = field.get(object) == null ? "" : field.get(object).toString();
                            flag = true;
                            break;
                        }
                    }
                }
                if(flag){
                    break;
                }
            }
            if(!StringUtils.isBlank(lockKey)){
                //获取redis锁
                if(redisLockUtils.lock(redisLock.key(),redisLock.waitTime())){
                    try {
                        //执行方法
                        Object object = pjp.proceed();
                        return object;
                    }finally {
                        //释放锁
                        redisLockUtils.releaseLock(redisLock.key());
                    }
                }else{
                    throw new BusinessException(BusinessExceptionEnum.GET_REDIS_LOCK_FAIL);
                }
            }else{
                //执行方法
                Object object = pjp.proceed();
                return object;
            }
        }
    }
    
    
  • 最后我们只需要在需要加锁的方法上加上上面的注解就能让这个方法使用分布式锁了

        @Override
        @RedisLock(type = UserInfoDTO.class,key = "userId",waitTime = 6000)
        public UserInfoDTO updateUserInfo(UserInfoDTO userInfoDTO){
            UserInfo userInfo = BeanUtils.dtoTodo(userInfoDTO,UserInfo.class);
            userInfoMapper.updateByPrimaryKey(userInfo);
            try {
                log.info("开始睡觉,time = {}",new Date());
                Thread.sleep(10000L);
                log.info("结束睡觉,time = {}",new Date());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return BeanUtils.doTodto(userInfo,UserInfoDTO.class);
        }
    
自定义注解实现分布式锁是一种在分布式系统中解决并发问题的方法。通过在需要加锁的方法上添加自定义注解,可以实现对该方法的并发控制。具体实现步骤如下: 1. 首先,在项目的pom文件中引入相关的依赖,以支持分布式锁的功能。 2. 在项目中创建一个新的目录,并使用元注解来定义自定义注解。这个自定义注解可以用来标记需要加锁的方法。 3. 在具体的业务实现类中,使用自定义注解来标记需要加锁的方法。这样,在方法执行时,会根据注解的配置来进行并发控制。 使用自定义注解实现分布式锁的好处是可以避免在每个需要加锁的方法中都引入相关的配置类和方法,提高了代码的可读性和可维护性。此外,还可以将配置和项目打包成jar包,方便在其他项目中引入使用。 分布式锁相对于普通锁的区别在于,普通锁只能在单体应用中锁住方法,而分布式锁可以在分布式系统中实现并发控制。在分布式系统中,不同实例之间共用代码和数据库,因此需要使用分布式锁来保证并发操作的正确性。分布式锁可以使用一些工具,如Redis,将锁放在共享的资源中,以实现多个实例共用一个锁的效果。 总结来说,自定义注解实现分布式锁是一种方便且可扩展的方式,可以在分布式系统中解决并发问题。 #### 引用[.reference_title] - *1* [自定义注解实现分布式锁](https://blog.csdn.net/qq_37205211/article/details/122140430)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [分布式编程-实现分布式锁-优雅的使用自定义注解实现](https://blog.csdn.net/qq_41692766/article/details/105842467)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [自定义注解,基于redis实现分布式锁](https://blog.csdn.net/weixin_43975276/article/details/131097829)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值