- 正常流程:
- 报异常情况:
- 流程:
- 正常流程:
- 出现异常情况:
3、两版本对比
针对后置通知和后环绕通知的位置发生了变化
二、Spring循环依赖 0、前置内容
- 实例化
申请内存空间,但未进行操作
- 初始化
对已申请的空间进行属性赋值,装修…等操作
- 总体相关对象
- A/B两对象在三级缓存中的迁移说明
1、什么是Spring循环依赖
多个bean之间相互依赖,形成闭环。A依赖B,B依赖C,C依赖A;
2、Spring内部的三级缓存
Spring解决循环引用的3个Map
3、Spring如何循环引用
三、Redis
-
命令不区分大小写,key区分大小写
-
help @类型名
help @string
2、各类型使用场景
-
String
-
常用指令
- set k1 v1
- get k1
-
同时设置/获取多个key
- mset k1 v1 k2 v2 k3 v3
- mget k1 k2 k3 …
-
数值增减
- incr k1
- incrby k1 2
- decr k1
- decrby k2 2
-
获取字符串长度
- strlen k1
-
分布式锁
- setnx k1 v1
- setnx k1 v1
-
引用场景
- 点赞数
- 喜欢数
- …
-
-
hash
- 应用场景
- 购物车
- 缓存对象
- 应用场景
-
list
- 应用场景
- 微信文章订阅公众号
- 应用场景
-
set
-
集合运算
-
应用场景
- 抽奖
- 点赞
- 社交关系
- 可能认识的人
- 共同关注/爱好等…
-
-
zset
- 应用场景
- 抖音热搜
- 根据某个值,对什么进行排序显示
- …
- 应用场景
3、分布式锁
- 自写锁存在的问题
- 续锁问题
- 张冠李戴问题,删错锁,自己只能删自己的锁
- 但不能使用lua脚本时,考虑redis自带的事务解决原子删除问题
- 解锁时在finally代码块中解锁
- 若服务单机,无法执行finllay代码块,就需要设置锁自带的过期时间
- 加锁和过期时间是同一行的原子操作
之前的文章
//从数据库查询数据【Redis分布式锁】 public Map> getCatelogJsonFromDBWithRedisLock() { String uuid = UUID.randomUUID().toString(); //设置redis分布式锁,30s自动删除锁 Boolean isLock = redisTemplate.opsForValue().setIfAbsent("lock", uuid,300L,TimeUnit.SECONDS); if (isLock){ //抢锁成功。。。执行业务 Map > resultMap = null; try { resultMap = getLongListMap(); }finally { //lua脚本解锁:让获取数据+对比数据成为原子操作 String script = "if redis.call("get",KEYS[1]) == ARGV[1] thenn" + " return redis.call("del",KEYS[1])n" + "elsen" + " return 0n" + "end"; Long lock = redisTemplate.execute(new DefaultRedisscript (script, Long.class),Arrays.asList("lock"),uuid); } return resultMap; }else { //抢锁失败。。。重试 try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } // 睡眠0.2s后,重新调用 //自旋 return getCatelogJsonFromDBWithRedisLock(); } }
- 官方推荐Redisson



