某乎我也写了,如果想直接用代码请直接搜索这个文章标题的某乎
(资料图片)
自定义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,可以去了解一下。
觉得可以的话点个赞是我持续分享的动力(努力提高我分享的水平)
关键词: