当前位置: 首页 > 文学 > 正文

自定义starter,注解,实现分布式锁

2023-07-09 12:05:35来源:哔哩哔哩

某乎我也写了,如果想直接用代码请直接搜索这个文章标题的某乎


(资料图片)

自定义RedissonClient-starter

依赖

<dependencies>  <dependency>    <groupId></groupId>    <artifactId>spring-boot-starter</artifactId>    <version></version>  </dependency>  <dependency>    <groupId></groupId>    <artifactId>spring-boot-autoconfigure</artifactId>    <version></version>  </dependency>  <dependency>    <groupId></groupId>    <artifactId>spring-boot-configuration-processor</artifactId>    <version></version>  </dependency>  <dependency>    <groupId></groupId>    <artifactId>lombok</artifactId>    <version></version>  </dependency>  <dependency>    <groupId></groupId>    <artifactId>redisson-spring-boot-starter</artifactId>    <version></version>  </dependency></dependencies>

基础配置类

ConfigurationProperties装载的时候会在properties/yaml/yml文件中找到前缀位my:caplock之后的配置注解。

请注意:对于装配的时候如果默认会my:caplock之后一级属性的作为配置类的的属性,如果存在my:caplock:lock1:one这种二级属性,此时one会作为lock1(可以看作新类)的一个属性,并且会存在装载配置问题。原因去看springBoot的中文文档,可以去看看springboot的外部配置这一板块

@EnableConfigurationProperties这种和@Value的区别之一是后者可以实现spel表达式的识别,文章下面的自定义注解这种就需要用对应的paser来进行执行语句表达获取value

SPEL:核心技术_Spring 框架文档 ()

@Setter@Getter@ConfigurationProperties("")public class RedisConfig { private String url; private boolean usage;}

配置类

@Configuration(proxyBeanMethods = false)@EnableConfigurationProperties()@Log4j2public class MyRedisCapLockConfig { @Bean public RedissonClient redissonClient(RedisConfig redisConfig) { if (()==false){ ("不启用redis分布式锁"); return null;        }        Config config = new Config();        ();        SingleServerConfig singleServerConfig = ();        (()); return (config);    }}

在当前项目的resources\META-INF的文件夹下出创建并附上以下内容。

=

点击idea下的将对应的maven模块的生命周期进行install保存该项目到本地仓库中

编辑

自定义注解

注意:请在启动类上加上扫描组件的注解,防止spring没有扫描到我们封装的bean,还有开启切面代理

@SpringBootApplication@ComponentScan({""})@EnableAspectJAutoProxypublic class RedisLockApplication {    public static void main(String[] args) {        (, args);    }}

编辑切换为居中

启动项目依赖

<dependencies>    <dependency>        <groupId></groupId>        <artifactId>spring-boot-starter-web</artifactId>    </dependency>    <dependency>        <groupId></groupId>        <artifactId>myRedisStarter</artifactId>        <version></version>    </dependency>    <dependency>        <groupId></groupId>        <artifactId>spring-boot-starter-test</artifactId>        <scope>test</scope>    </dependency>    <dependency>        <groupId></groupId>        <artifactId>spring-boot-starter-aop</artifactId>    </dependency></dependencies>

目前我们实现的是一个实现分布式锁功能的注解Lock

import .*;/** * @Author luYu * @Date 2023/7/8 13:19 */@Retention() //在执行时有效@Target({}) //允许在方法注解@Repeatable() //允许重复注解,前提必须是实现了拥有该目标注解的名字为value的注释数组@Documented //javadoc 上下文运行@Inherited  // 继承public @interface Lock {    // 锁住的key    String lockKey()default "";    // 锁住的时间    int lockTime()default 5;    @Retention()    @Target()    @Inherited    @Documented    public @interface Locks {        Lock[] value();    }}

相关切面

@Component@Aspectpublic class LockAspect { @Resource private RedissonClient redissonClient; @Around("@annotation()||@annotation()") public void getvoid(ProceedingJoinPoint joinPoint){        MethodSignature signature = ((MethodSignature) ()); Lock[] annos = ().getAnnotationsByType(); getLock(toLock -> {            ArrayList<RLock> rLocks = new ArrayList<>(); for (Lock anno : toLock) {                RLock lock = (()); try { boolean b = ((), ); if (!b){ throw new RuntimeException("上锁失败:"+());                    }                    (lock); ();                } catch (InterruptedException e) {                    (); throw new RuntimeException("上锁失败:"+());                } catch (Throwable e) { throw new RuntimeException(e);                } finally { unLock(rLocks);                }            }        }, annos);    } public static void getLock(Consumer<Lock[]> consumer, Lock... locks) {        (locks);    } public static void unLock(ArrayList<RLock> rLocks) { if (()) { return;        } for (RLock rLock : rLocks) { if (() && ()){                ();                ("解锁:"+());            }        }    }}

接口

@RestController@RequestMapping("/1")public class LockController { @GetMapping("/ad") @Lock(lockKey = "luyu",lockTime = 4) @Lock(lockKey = "luyu1",lockTime = 3) @SneakyThrows public void  getLock(){ try {            (2);        } finally {            ("鲈鱼来了");        }    }}

结果:

因为我在aop重复执行();就输出了两次鲈鱼来了,不要在意细节哈哈。

编辑切换为居中

给大家留了一个坑,@SneakyThrows和很多catach,可以去了解一下。

觉得可以的话点个赞是我持续分享的动力(努力提高我分享的水平)

关键词: