博客缓存的那些事?

技术小能手 2018-11-27

LOG Cache string exception class

一、写在前面

最近博客的前端展示系统基本高一段落了,切换一下数据源,看看连接生产的数据试试效果,结果不是很理想,光一个首页就触发很多sql语句,为了能够缩短首页的加载时间,特做了几点优化。

1b745c599db48f33e25aea734e2e2b8a10493c2a

 ●  系统启动时,加载常用的变量
 ●  service做了一层通用的缓存拦截控制

二、系统启动加载缓存


  1. @Component

  2. @Order(1)

  3. public class CacheInit implements CommandLineRunner {

  4. private static final Logger log = LoggerFactory.getLogger(CacheInit.class);

  5. @Autowired

  6. private RedisTemplate<String,Object> redisTemplate;

  7. @Autowired

  8. private WpOptionsService wpOptionsService;

  9. /**

  10. * @param args

  11. * @throws Exception

  12. * @see org.springframework.boot.CommandLineRunner#run(java.lang.String[])

  13. */

  14. @Override

  15. public void run(String args) throws Exception {

  16. log.info(“>>>>>>>>>>>>>加载缓存数据开始<<<<<<<<<<<<<<<<<<<<<<“);

  17. Map<String,String> map= new HashMap<String,String>();

  18. List<WpOptions> list =wpOptionsService.autoloadConfig();

  19. for(WpOptions wpOptions:list){

  20. if(!StringUtils.isEmpty(wpOptions.getOptionValue())){

  21. map.put(wpOptions.getOptionName(), wpOptions.getOptionValue());

  22. }

  23. }

  24. log.info(“加载系统配置信息:”+list.size());

  25. redisTemplate.opsForValue().set(RedisConstant.autoloadConfig, map);

  26. //Object test =redisTemplate.opsForValue().get(“test”);

  27. //log.info(“取出缓存数据:”+test.toString());

  28. log.info(“>>>>>>>>>>>>>初始化缓存数据 结束<<<<<<<<<<<<<<<<<<<<<<“);

  29. }

  30. }

三、Service实现通用缓存控制:

大概思路如下:

1.新增一个注解,针对特定的注解进行拦截
2.设置一个通用的key生成算法
3.对缓存进行逻辑的判断

新增一个注解@RedisCache,对有需要的缓存的方法进行添加设置


  1. @Target({ElementType.METHOD})

  2. @Retention(RetentionPolicy.RUNTIME)

  3. @Inherited

  4. public @interface RedisCache {

  5. /**

  6. * 业务的名称

  7. */

  8. String value() default “”;

  9. /**

  10. * redis缓存的Key(默认类名-方法名-自定义key)

  11. */

  12. String key() default “”;

  13. /**

  14. * 是否刷新缓存,默认false

  15. */

  16. boolean flush() default false;

  17. /**

  18. * 缓存失效时间,默认30

  19. */

  20. long expire() default 30L;

  21. /**

  22. * 缓存时间单位,默认天

  23. */

  24. TimeUnit unit() default TimeUnit.DAYS;

  25. }

拦截代码


  1. @Pointcut(value = @annotation(cn.liuhaihua.web.annotation.RedisCache)”)

  2. public void pointcut() {

  3. }

key通用的生成算法


  1. /**

  2. * 获取切面缓存的key

  3. *

  4. * @param point

  5. * 当前切面执行的方法

  6. * @param extra

  7. * 额外的参数 (非必选)

  8. * @param prefix

  9. * key前缀 (非必选)

  10. * @throws NoSuchMethodException

  11. */

  12. public static String getKey(ProceedingJoinPoint point, String extra, String prefix) throws NoSuchMethodException {

  13. Method currentMethod = AspectUtil.getMethod(point);

  14. String methodName = currentMethod.getName();

  15. StringBuilder key = new StringBuilder();

  16. key.append(getKeyOfClassPrefix(point, prefix));

  17. key.append(“_”);

  18. key.append(methodName);

  19. key.append(getMethodParamsKey(point.getArgs()));

  20. key.append(null == extra ? “” : extra);

  21. return key.toString();

  22. }

对拦截的方法进行缓存逻辑处理


  1. @Around(“pointcut()”)

  2. public Object handle(ProceedingJoinPoint point) throws Throwable {

  3. Method currentMethod = AspectUtil.getMethod(point);

  4. //获取操作名称

  5. RedisCache cache = currentMethod.getAnnotation(RedisCache.class);

  6. boolean flush = cache.flush();

  7. if (flush) {

  8. String classPrefix = AspectUtil.getKeyOfClassPrefix(point, BIZ_CACHE_PREFIX);

  9. log.info(“清空缓存 {}*”, classPrefix);

  10. redisService.delBatch(classPrefix);

  11. return point.proceed();

  12. }

  13. //通用缓存

  14. String key = AspectUtil.getKey(point, cache.key(), BIZ_CACHE_PREFIX);

  15. log.info(“生成的KEY名字:{}”, key);

  16. boolean hasKey = redisService.hasKey(key);

  17. if (hasKey) {

  18. try {

  19. log.info(“{}从缓存中获取数据”, key);

  20. return redisService.get(key);

  21. } catch (Exception e) {

  22. log.error(“从缓存中获取数据失败!”, e);

  23. }

  24. }

  25. //先执行业务

  26. Object result = point.proceed();

  27. redisService.set(key, result, cache.expire(), cache.unit());

  28. log.info(“{}从数据库中获取数据”, key);

  29. return result;

  30. }

四、如何使用

代码如下


  1. @Override

  2. @RedisCache

  3. public List<WpLinks> getLinks(String linkrel) {

  4. if(StringUtils.isEmpty(linkrel) ){

  5. return wpLinksMapper.selectAll();

  6. }else{

  7. Example example = new Example(WpLinks.class);

  8. Criteria criteria = example.createCriteria();

  9. criteria.andEqualTo(“linkRel”, LinkConstant.LINK_REL_FRIEND);

  10. return wpLinksMapper.selectByExample(example);

  11. }

  12. }

效果


  1. INFO | 2018-11-26 14:06:57,264 | JWordpres-v2.0 | [http-nio-8090-exec-1-14] (c.l.w.a.RedisCacheAspect:70) | 生成的KEY名字:biz_cache_cn_liuhaihua_web_service_impl_WpLinksServiceImpl_getLinks(‘friend’)

  2. INFO | 2018-11-26 14:06:57,281 | JWordpres-v2.0 | [http-nio-8090-exec-1-14] (c.l.w.a.RedisCacheAspect:74) | biz_cache_cn_liuhaihua_web_service_impl_WpLinksServiceImpl_getLinks(‘friend’)从缓存中获取数据


原文发布时间为:2018-11-27

本文作者:HARRIES

本文来自云栖社区合作伙伴“Java杂记”,了解相关信息可以关注“Java杂记”。

登录 后评论
下一篇
corcosa
10912人浏览
2019-10-08
相关推荐
内存那些事
1047人浏览
2016-05-17 13:23:55
内存那些事
590人浏览
2018-01-07 16:45:11
TCP报文发送的那些事
593人浏览
2019-04-18 22:21:11
0
0
0
623