正在显示
8 个修改的文件
包含
83 行增加
和
27 行删除
@@ -19,8 +19,8 @@ public @interface RedisCacheable { | @@ -19,8 +19,8 @@ public @interface RedisCacheable { | ||
19 | //缓存key,KEY的名称必须是【#+参数的名称,或者#+{对象名称}】,参考spel表达式 | 19 | //缓存key,KEY的名称必须是【#+参数的名称,或者#+{对象名称}】,参考spel表达式 |
20 | String cacheKey(); | 20 | String cacheKey(); |
21 | 21 | ||
22 | - //有效期时间(单位:秒),默认8个小时 | ||
23 | - int expire() default 28800; | 22 | + //有效期时间(单位:秒),默认5分钟 |
23 | + int expire() default 5*60; | ||
24 | 24 | ||
25 | //缓存主动刷新时间(单位:秒),默认不主动刷新 | 25 | //缓存主动刷新时间(单位:秒),默认不主动刷新 |
26 | int reflash() default -1; | 26 | int reflash() default -1; |
@@ -6,9 +6,12 @@ import com.tianbo.warehouse.annotation.cache.annotation.RedisCachePut; | @@ -6,9 +6,12 @@ import com.tianbo.warehouse.annotation.cache.annotation.RedisCachePut; | ||
6 | import com.tianbo.warehouse.annotation.cache.annotation.RedisCacheable; | 6 | import com.tianbo.warehouse.annotation.cache.annotation.RedisCacheable; |
7 | import com.tianbo.warehouse.annotation.cache.util.JDKSerializeUtil; | 7 | import com.tianbo.warehouse.annotation.cache.util.JDKSerializeUtil; |
8 | import com.tianbo.warehouse.annotation.cache.util.redis.DefaultKeyGenerator; | 8 | import com.tianbo.warehouse.annotation.cache.util.redis.DefaultKeyGenerator; |
9 | +import com.tianbo.warehouse.util.RedisUtils; | ||
9 | import lombok.extern.slf4j.Slf4j; | 10 | import lombok.extern.slf4j.Slf4j; |
11 | +import org.apache.commons.lang.StringUtils; | ||
10 | import org.aspectj.lang.ProceedingJoinPoint; | 12 | import org.aspectj.lang.ProceedingJoinPoint; |
11 | import org.aspectj.lang.Signature; | 13 | import org.aspectj.lang.Signature; |
14 | +import org.aspectj.lang.annotation.After; | ||
12 | import org.aspectj.lang.annotation.Around; | 15 | import org.aspectj.lang.annotation.Around; |
13 | import org.aspectj.lang.annotation.Aspect; | 16 | import org.aspectj.lang.annotation.Aspect; |
14 | import org.springframework.beans.factory.annotation.Autowired; | 17 | import org.springframework.beans.factory.annotation.Autowired; |
@@ -17,6 +20,8 @@ import org.springframework.data.redis.core.ValueOperations; | @@ -17,6 +20,8 @@ import org.springframework.data.redis.core.ValueOperations; | ||
17 | import org.springframework.stereotype.Component; | 20 | import org.springframework.stereotype.Component; |
18 | 21 | ||
19 | import javax.annotation.Resource; | 22 | import javax.annotation.Resource; |
23 | +import java.util.Objects; | ||
24 | +import java.util.Set; | ||
20 | import java.util.concurrent.TimeUnit; | 25 | import java.util.concurrent.TimeUnit; |
21 | 26 | ||
22 | @Aspect | 27 | @Aspect |
@@ -49,16 +54,18 @@ public class RedisCacheableAspect { | @@ -49,16 +54,18 @@ public class RedisCacheableAspect { | ||
49 | ValueOperations<String, Object> valueOper = redisTemplate.opsForValue(); | 54 | ValueOperations<String, Object> valueOper = redisTemplate.opsForValue(); |
50 | byte[] value = (byte[]) valueOper.get(key); | 55 | byte[] value = (byte[]) valueOper.get(key); |
51 | if(value != null){ | 56 | if(value != null){ |
57 | + log.info("[CACHE-HIT]-命中:[{}],缓存时效:[{}]分",key,redisTemplate.getExpire(key, TimeUnit.MINUTES)); | ||
52 | //如果缓存有值,需要判断刷新缓存设置和当前缓存的失效时间 | 58 | //如果缓存有值,需要判断刷新缓存设置和当前缓存的失效时间 |
53 | int reflash = cache.reflash(); | 59 | int reflash = cache.reflash(); |
54 | - if(reflash > 0){ | 60 | + if(reflash > 0 && StringUtils.isNotEmpty(key)){ |
55 | //查询当前缓存失效时间是否在主动刷新规则范围内 | 61 | //查询当前缓存失效时间是否在主动刷新规则范围内 |
56 | long exp = redisTemplate.getExpire(key, TimeUnit.SECONDS); | 62 | long exp = redisTemplate.getExpire(key, TimeUnit.SECONDS); |
57 | if(exp <= reflash){ | 63 | if(exp <= reflash){ |
58 | //主动刷新缓存,为不影响本次获取效率,采用异步线程刷新缓存 | 64 | //主动刷新缓存,为不影响本次获取效率,采用异步线程刷新缓存 |
59 | } | 65 | } |
60 | } | 66 | } |
61 | - return JDKSerializeUtil.unserialize(value); | 67 | + valueData = JDKSerializeUtil.unserialize(value); |
68 | + return valueData; | ||
62 | } | 69 | } |
63 | //缓存中没有值,执行实际数据查询方法 | 70 | //缓存中没有值,执行实际数据查询方法 |
64 | if(valueData == null) { | 71 | if(valueData == null) { |
@@ -66,9 +73,13 @@ public class RedisCacheableAspect { | @@ -66,9 +73,13 @@ public class RedisCacheableAspect { | ||
66 | } | 73 | } |
67 | //写入缓存 | 74 | //写入缓存 |
68 | if(cache.expire() > 0) { | 75 | if(cache.expire() > 0) { |
69 | - valueOper.set(key, JDKSerializeUtil.serialize(valueData),cache.expire(),TimeUnit.SECONDS); //否则设置缓存时间 ,序列化存储 | 76 | + //否则设置缓存时间 ,序列化存储 |
77 | + valueOper.set(key, Objects.requireNonNull(JDKSerializeUtil.serialize(valueData)),cache.expire(),TimeUnit.SECONDS); | ||
78 | + log.info("[CACHE-SET]-已设置缓存:[{}],缓存时效:[{}秒]",key,cache.expire()); | ||
70 | } else { | 79 | } else { |
71 | - valueOper.set(key, JDKSerializeUtil.serialize(valueData)); | 80 | + //永不过期 |
81 | + valueOper.set(key, Objects.requireNonNull(JDKSerializeUtil.serialize(valueData))); | ||
82 | + log.info("[CACHE-SET]-已设置永久缓存:[{}]",key); | ||
72 | } | 83 | } |
73 | } | 84 | } |
74 | return valueData; | 85 | return valueData; |
@@ -89,15 +100,17 @@ public class RedisCacheableAspect { | @@ -89,15 +100,17 @@ public class RedisCacheableAspect { | ||
89 | public Object cachePut (final ProceedingJoinPoint pjp , RedisCachePut cacheput) throws Throwable{ | 100 | public Object cachePut (final ProceedingJoinPoint pjp , RedisCachePut cacheput) throws Throwable{ |
90 | try{ | 101 | try{ |
91 | //生成缓存KEY | 102 | //生成缓存KEY |
92 | - String[] keys = defaultKeyGenerator.generateKey(pjp, cacheput.cacheNames(), cacheput.cacheKey()); | 103 | +// String[] keys = defaultKeyGenerator.generateKey(pjp, cacheput.cacheNames(), cacheput.cacheKey()); |
104 | + String[] keys = defaultKeyGenerator.generateKey(pjp, cacheput.cacheKey()); | ||
93 | Object valueData = pjp.proceed(); | 105 | Object valueData = pjp.proceed(); |
94 | //写入缓存 | 106 | //写入缓存 |
95 | for(String key : keys){ | 107 | for(String key : keys){ |
96 | ValueOperations<String, Object> valueOper = redisTemplate.opsForValue(); | 108 | ValueOperations<String, Object> valueOper = redisTemplate.opsForValue(); |
97 | if(cacheput.expire() > 0) { | 109 | if(cacheput.expire() > 0) { |
98 | - valueOper.set(key, JDKSerializeUtil.serialize(pjp.getArgs()[0]),cacheput.expire(),TimeUnit.SECONDS); | 110 | + valueOper.set(key, Objects.requireNonNull(JDKSerializeUtil.serialize(valueData)),cacheput.expire(),TimeUnit.SECONDS); |
111 | + log.info("[CACHE-SET]-更新缓存:[{}],缓存时效:[{}秒]",key,cacheput.expire()); | ||
99 | } else { | 112 | } else { |
100 | - valueOper.set(key, JDKSerializeUtil.serialize(pjp.getArgs()[0])); | 113 | + valueOper.set(key, Objects.requireNonNull(JDKSerializeUtil.serialize(valueData))); |
101 | } | 114 | } |
102 | } | 115 | } |
103 | return valueData; | 116 | return valueData; |
@@ -151,6 +164,7 @@ public class RedisCacheableAspect { | @@ -151,6 +164,7 @@ public class RedisCacheableAspect { | ||
151 | @Around(value = "@annotation(redisCacheDelTarget)") | 164 | @Around(value = "@annotation(redisCacheDelTarget)") |
152 | public Object cacheEvict (final ProceedingJoinPoint pjp , RedisCacheDelTarget redisCacheDelTarget) throws Throwable{ | 165 | public Object cacheEvict (final ProceedingJoinPoint pjp , RedisCacheDelTarget redisCacheDelTarget) throws Throwable{ |
153 | try{ | 166 | try{ |
167 | + Set<String> deleteBatchByKeys = RedisUtils.deleteBatchByKeys(redisCacheDelTarget.cacheKey()); | ||
154 | String cacheKey = redisCacheDelTarget.cacheKey(); | 168 | String cacheKey = redisCacheDelTarget.cacheKey(); |
155 | boolean allEntries = redisCacheDelTarget.allEntries(); | 169 | boolean allEntries = redisCacheDelTarget.allEntries(); |
156 | if(allEntries){ | 170 | if(allEntries){ |
@@ -51,8 +51,9 @@ public class DefaultKeyGenerator { | @@ -51,8 +51,9 @@ public class DefaultKeyGenerator { | ||
51 | MethodSignature methodSignature = (MethodSignature) signature; | 51 | MethodSignature methodSignature = (MethodSignature) signature; |
52 | String targetClassName = pjp.getTarget().getClass().getName(); | 52 | String targetClassName = pjp.getTarget().getClass().getName(); |
53 | String targetMethodName = methodSignature.getName(); | 53 | String targetMethodName = methodSignature.getName(); |
54 | - //method参数列表 | 54 | + //method参数名 |
55 | String[] parameterNames = methodSignature.getParameterNames(); | 55 | String[] parameterNames = methodSignature.getParameterNames(); |
56 | + //method参数值 | ||
56 | Object[] args = pjp.getArgs(); | 57 | Object[] args = pjp.getArgs(); |
57 | 58 | ||
58 | StringBuffer sb = new StringBuffer(); | 59 | StringBuffer sb = new StringBuffer(); |
@@ -98,21 +99,20 @@ public class DefaultKeyGenerator { | @@ -98,21 +99,20 @@ public class DefaultKeyGenerator { | ||
98 | * 开始生成缓存key名称 | 99 | * 开始生成缓存key名称 |
99 | */ | 100 | */ |
100 | MethodSignature methodSignature = (MethodSignature) signature; | 101 | MethodSignature methodSignature = (MethodSignature) signature; |
101 | - String targetClassName = pjp.getTarget().getClass().getName(); | 102 | + String targetClassName = pjp.getTarget().getClass().getSimpleName(); |
102 | String targetMethodName = methodSignature.getName(); | 103 | String targetMethodName = methodSignature.getName(); |
103 | //method参数列表 | 104 | //method参数列表 |
104 | String[] parameterNames = methodSignature.getParameterNames(); | 105 | String[] parameterNames = methodSignature.getParameterNames(); |
105 | Object[] args = pjp.getArgs(); | 106 | Object[] args = pjp.getArgs(); |
106 | 107 | ||
107 | StringBuffer sb = new StringBuffer(); | 108 | StringBuffer sb = new StringBuffer(); |
108 | - sb.append(targetClassName).append("_") | ||
109 | - .append(targetMethodName).append("_") | ||
110 | - .append(cacheKey).append("_"); | 109 | + sb.append(cacheKey).append(":").append(targetClassName).append(":") |
110 | + .append(targetMethodName).append(":"); | ||
111 | //evaluationContext存储参数的kEY与Value | 111 | //evaluationContext存储参数的kEY与Value |
112 | for(int i = 0; i < parameterNames.length; i++){ | 112 | for(int i = 0; i < parameterNames.length; i++){ |
113 | String parameterName = parameterNames[i]; | 113 | String parameterName = parameterNames[i]; |
114 | - sb.append("P").append(parameterName).append("_") | ||
115 | - .append("V").append(args[i]).append("_"); | 114 | + sb.append("P").append(parameterName).append(":") |
115 | + .append("V").append(args[i]).append(":"); | ||
116 | evaluationContext.setVariable(parameterName,args[i]); | 116 | evaluationContext.setVariable(parameterName,args[i]); |
117 | } | 117 | } |
118 | 118 |
@@ -192,7 +192,7 @@ public class PermissionServiceImp implements PermissionService { | @@ -192,7 +192,7 @@ public class PermissionServiceImp implements PermissionService { | ||
192 | } | 192 | } |
193 | 193 | ||
194 | @Override | 194 | @Override |
195 | -// @RedisCacheable(cacheKey = "getUserMenuTreeByUserId") | 195 | + @RedisCacheable(cacheKey = "getUserMenuTreeByUserId") |
196 | public List<PERMISSION> getUserMenuTreeByUserId(@NotNull Integer userId) { | 196 | public List<PERMISSION> getUserMenuTreeByUserId(@NotNull Integer userId) { |
197 | List<PERMISSION> loginedUserMenus = permissionMapper.getUserMenuTreeByUserId(userId); | 197 | List<PERMISSION> loginedUserMenus = permissionMapper.getUserMenuTreeByUserId(userId); |
198 | List<PERMISSION> loginedUserMenusTree = loginedUserMenus.stream() | 198 | List<PERMISSION> loginedUserMenusTree = loginedUserMenus.stream() |
@@ -3,6 +3,7 @@ package com.tianbo.warehouse.service.imp; | @@ -3,6 +3,7 @@ package com.tianbo.warehouse.service.imp; | ||
3 | import com.github.pagehelper.Page; | 3 | import com.github.pagehelper.Page; |
4 | import com.github.pagehelper.PageHelper; | 4 | import com.github.pagehelper.PageHelper; |
5 | import com.github.pagehelper.PageInfo; | 5 | import com.github.pagehelper.PageInfo; |
6 | +import com.tianbo.warehouse.annotation.cache.annotation.RedisCacheDelTarget; | ||
6 | import com.tianbo.warehouse.dao.DepartmentMapper; | 7 | import com.tianbo.warehouse.dao.DepartmentMapper; |
7 | import com.tianbo.warehouse.dao.ROLEMapper; | 8 | import com.tianbo.warehouse.dao.ROLEMapper; |
8 | import com.tianbo.warehouse.dao.RolePermissionMapper; | 9 | import com.tianbo.warehouse.dao.RolePermissionMapper; |
@@ -90,6 +91,7 @@ public class RoleServiceImp implements RoleService{ | @@ -90,6 +91,7 @@ public class RoleServiceImp implements RoleService{ | ||
90 | return roleMapper.insertSelective(record); | 91 | return roleMapper.insertSelective(record); |
91 | } | 92 | } |
92 | 93 | ||
94 | + @RedisCacheDelTarget(cacheKey = "getUserMenuTreeByUserId") | ||
93 | @Transactional(rollbackFor = Exception.class) | 95 | @Transactional(rollbackFor = Exception.class) |
94 | @Override | 96 | @Override |
95 | public int setRolePermissoin(RolePermission record){ | 97 | public int setRolePermissoin(RolePermission record){ |
@@ -3,6 +3,7 @@ package com.tianbo.warehouse.service.imp; | @@ -3,6 +3,7 @@ package com.tianbo.warehouse.service.imp; | ||
3 | import com.github.pagehelper.Page; | 3 | import com.github.pagehelper.Page; |
4 | import com.github.pagehelper.PageHelper; | 4 | import com.github.pagehelper.PageHelper; |
5 | import com.github.pagehelper.PageInfo; | 5 | import com.github.pagehelper.PageInfo; |
6 | +import com.tianbo.warehouse.annotation.cache.annotation.RedisCacheDelTarget; | ||
6 | import com.tianbo.warehouse.dao.PERMISSIONMapper; | 7 | import com.tianbo.warehouse.dao.PERMISSIONMapper; |
7 | import com.tianbo.warehouse.dao.ROLEMapper; | 8 | import com.tianbo.warehouse.dao.ROLEMapper; |
8 | import com.tianbo.warehouse.dao.USERSMapper; | 9 | import com.tianbo.warehouse.dao.USERSMapper; |
@@ -14,6 +15,7 @@ import com.tianbo.warehouse.model.UserRole; | @@ -14,6 +15,7 @@ import com.tianbo.warehouse.model.UserRole; | ||
14 | import com.tianbo.warehouse.service.PermissionService; | 15 | import com.tianbo.warehouse.service.PermissionService; |
15 | import com.tianbo.warehouse.service.UserService; | 16 | import com.tianbo.warehouse.service.UserService; |
16 | import org.springframework.beans.factory.annotation.Autowired; | 17 | import org.springframework.beans.factory.annotation.Autowired; |
18 | +import org.springframework.cache.annotation.Cacheable; | ||
17 | import org.springframework.stereotype.Service; | 19 | import org.springframework.stereotype.Service; |
18 | import org.springframework.transaction.annotation.Transactional; | 20 | import org.springframework.transaction.annotation.Transactional; |
19 | 21 | ||
@@ -23,6 +25,7 @@ import java.util.Collections; | @@ -23,6 +25,7 @@ import java.util.Collections; | ||
23 | import java.util.List; | 25 | import java.util.List; |
24 | import java.util.Random; | 26 | import java.util.Random; |
25 | 27 | ||
28 | +@Cacheable | ||
26 | @Service(value = "userService") | 29 | @Service(value = "userService") |
27 | public class UserServiceImpl implements UserService{ | 30 | public class UserServiceImpl implements UserService{ |
28 | 31 | ||
@@ -153,6 +156,7 @@ public class UserServiceImpl implements UserService{ | @@ -153,6 +156,7 @@ public class UserServiceImpl implements UserService{ | ||
153 | * @return | 156 | * @return |
154 | */ | 157 | */ |
155 | @Override | 158 | @Override |
159 | + @RedisCacheDelTarget(cacheKey = "getUserMenuTreeByUserId") | ||
156 | @Transactional(rollbackFor = Exception.class) | 160 | @Transactional(rollbackFor = Exception.class) |
157 | public int setUserRole(UserRole userRole){ | 161 | public int setUserRole(UserRole userRole){ |
158 | try{ | 162 | try{ |
@@ -166,10 +170,6 @@ public class UserServiceImpl implements UserService{ | @@ -166,10 +170,6 @@ public class UserServiceImpl implements UserService{ | ||
166 | userRoleMapper.insertSelective(ur); | 170 | userRoleMapper.insertSelective(ur); |
167 | } | 171 | } |
168 | } | 172 | } |
169 | - /** | ||
170 | - * 重写redis用户权限等相关资料 | ||
171 | - */ | ||
172 | - | ||
173 | return 1; | 173 | return 1; |
174 | }catch (Exception e){ | 174 | }catch (Exception e){ |
175 | e.printStackTrace(); | 175 | e.printStackTrace(); |
1 | package com.tianbo.warehouse.util; | 1 | package com.tianbo.warehouse.util; |
2 | import org.springframework.beans.factory.annotation.Autowired; | 2 | import org.springframework.beans.factory.annotation.Autowired; |
3 | import org.springframework.boot.actuate.health.CompositeHealthIndicator; | 3 | import org.springframework.boot.actuate.health.CompositeHealthIndicator; |
4 | -import org.springframework.data.redis.core.BoundListOperations; | ||
5 | -import org.springframework.data.redis.core.StringRedisTemplate; | 4 | +import org.springframework.data.redis.core.*; |
6 | import org.springframework.stereotype.Component; | 5 | import org.springframework.stereotype.Component; |
7 | import org.springframework.util.CollectionUtils; | 6 | import org.springframework.util.CollectionUtils; |
8 | 7 | ||
9 | -import java.util.List; | ||
10 | -import java.util.Map; | ||
11 | -import java.util.Set; | 8 | +import javax.annotation.PostConstruct; |
9 | +import java.nio.charset.StandardCharsets; | ||
10 | +import java.util.*; | ||
12 | import java.util.concurrent.TimeUnit; | 11 | import java.util.concurrent.TimeUnit; |
13 | 12 | ||
14 | 13 | ||
@@ -27,6 +26,14 @@ public class RedisUtils { | @@ -27,6 +26,14 @@ public class RedisUtils { | ||
27 | this.redisTemplate = redisTemplate; | 26 | this.redisTemplate = redisTemplate; |
28 | } | 27 | } |
29 | 28 | ||
29 | + public static RedisUtils redisUtils; | ||
30 | + | ||
31 | + @PostConstruct | ||
32 | + public void init(){ | ||
33 | + redisUtils = this; | ||
34 | + redisUtils.redisTemplate=this.redisTemplate; | ||
35 | + } | ||
36 | + | ||
30 | /** | 37 | /** |
31 | * 指定缓存失效时间 | 38 | * 指定缓存失效时间 |
32 | * @param key 键 | 39 | * @param key 键 |
@@ -83,6 +90,39 @@ public class RedisUtils { | @@ -83,6 +90,39 @@ public class RedisUtils { | ||
83 | } | 90 | } |
84 | } | 91 | } |
85 | 92 | ||
93 | + /** | ||
94 | + * 【 递归删除redis key-value 】 | ||
95 | + * 效率会低点 但是删除方法安全 | ||
96 | + * @author yangjunxiong | ||
97 | + * @date 2021/6/21 10:05 | ||
98 | + **/ | ||
99 | + public static Set<String> deleteBatchByKeys(String key) { | ||
100 | + Set<String> keys = new HashSet<>(); | ||
101 | + redisUtils.redisTemplate.execute((RedisCallback<Set<String>>) connection -> { | ||
102 | + try (Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder() | ||
103 | + .match(key + "*") | ||
104 | + .count(5000).build())) { | ||
105 | + while (cursor.hasNext()) { | ||
106 | + keys.add(new String(cursor.next(), StandardCharsets.UTF_8)); | ||
107 | + } | ||
108 | + } catch (Exception e) { | ||
109 | + throw new RuntimeException(e); | ||
110 | + } | ||
111 | + return keys; | ||
112 | + }); | ||
113 | + if (CollectionUtils.isEmpty(keys)) { | ||
114 | + return Collections.emptySet(); | ||
115 | + } | ||
116 | + for (String key1 : keys) { | ||
117 | + redisUtils.redisTemplate.delete(key1); | ||
118 | + } | ||
119 | + if (!CollectionUtils.isEmpty(keys)) { | ||
120 | + return RedisUtils.deleteBatchByKeys(key); | ||
121 | + } | ||
122 | + return keys; | ||
123 | + } | ||
124 | + | ||
125 | + | ||
86 | //============================String============================= | 126 | //============================String============================= |
87 | /** | 127 | /** |
88 | * 普通缓存获取 | 128 | * 普通缓存获取 |
@@ -232,7 +232,7 @@ WHERE | @@ -232,7 +232,7 @@ WHERE | ||
232 | where role_id = #{roleId,jdbcType=INTEGER} | 232 | where role_id = #{roleId,jdbcType=INTEGER} |
233 | </update> | 233 | </update> |
234 | 234 | ||
235 | - <select id="findAll" parameterType="java.lang.String" resultMap="TreeWithResultMap"> | 235 | + <select id="findAll" parameterType="java.lang.String" resultMap="TreeWithPermResultMap"> |
236 | SELECT | 236 | SELECT |
237 | <include refid="Base_Column_List" /> | 237 | <include refid="Base_Column_List" /> |
238 | FROM role | 238 | FROM role |
-
请 注册 或 登录 后发表评论