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

使用Spring Boot和自定义缓存注解优化应用性能

在现代应用开发中,缓存是提高系统性能和响应速度的关键技术之一。Spring Boot提供了强大的缓存支持,但有时我们需要更灵活的缓存控制。本文将介绍如何使用Spring Boot和自定义缓存注解来优化应用性能。

1. 为什么需要自定义缓存注解?

Spring Boot提供了@Cacheable@CachePut@CacheEvict等注解来管理缓存,但有时这些注解可能无法满足特定需求。例如,你可能需要更细粒度的缓存控制,或者希望在缓存中存储自定义数据结构。这时,自定义缓存注解就显得尤为重要。

2. 创建自定义缓存注解

首先,我们需要创建一个自定义的缓存注解。这个注解将允许我们指定缓存的键和过期时间。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CustomCacheable {/***  缓存名称* @return*/String key() default "";/***  缓存条件* @return*/String condition() default "";/*** 过期时间,单位秒*/long expireTime() default 0;}
3. 创建缓存切面

接下来,我们需要创建一个切面来处理自定义缓存注解。这个切面将拦截带有自定义缓存注解的方法,并根据注解的参数进行缓存操作。

@Aspect
@Component
public class CustomCacheAspect {@Resourceprivate RedisTemplate<String, Object> redisTemplate;@Around("@annotation(customCacheable)")public Object cache(ProceedingJoinPoint joinPoint, CustomCacheable customCacheable) throws Throwable {String key = customCacheable.key();long expireTime = customCacheable.expireTime();//获取方法名及参数值String methodName = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();// 构建缓存键key = key + ":" + methodName;if (args != null && args.length > 0) {for (Object arg : args) {key = key + ":" + arg;}}//获取方法参数名
//        String[] parameterNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
//        if (parameterNames != null) {
//            for (int i = 0; i < parameterNames.length; i++) {
//                key = key + ":" + args[i];
//            }
//        }// 尝试从缓存中获取数据Object cachedValue = redisTemplate.opsForValue().get(key);if (cachedValue != null) {return cachedValue;}// 如果缓存中没有数据,则执行方法并将结果存入缓存Object result = joinPoint.proceed();if(expireTime > 0){redisTemplate.opsForValue().set(key, result, expireTime, TimeUnit.SECONDS);}else{redisTemplate.opsForValue().set(key, result);}return result;}
}
4. 配置RedisTemplate

为了在切面中使用RedisTemplate,我们需要进行相应的配置。

:这里RedisConnectionFactory Bean 可不配,不过会有提示,看着不爽。

@Configuration
public class RedisConfig {@Beanpublic RedisConnectionFactory redisConnectionFactory() {return new LettuceConnectionFactory(); // 或者使用JedisConnectionFactory等其他实现}@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new GenericJackson2JsonRedisSerializer());return template;}
}

 这里使用的依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.7.0</version></dependency>
5. 使用自定义缓存注解

最后,我们可以在服务类中使用自定义缓存注解,这里使用的上一篇生成的代码测试一下。

    /*** 根据id查询*/@GetMapping("/{id}")@CustomCacheable(key = "user")public  UserTest getById(@PathVariable Long id) {return userTestService.getById(id);}
6. 启用AOP支持

确保在你的Spring Boot应用中启用了AOP支持。你可以在application.properties中添加以下配置:

spring.aop.auto=true

或者在启动类上添加@EnableAspectJAutoProxy注解:

@SpringBootApplication
@EnableAspectJAutoProxy
public class AppStart  {public static void main(String[] args){SpringApplication.run(AppStart.class, args);}
}
7.测试

 

8.总结

通过自定义缓存注解和切面,我们可以在Spring Boot应用中实现更灵活的缓存控制。这不仅提高了应用的性能,还使得缓存管理更加便捷和高效。希望本文对你在Spring Boot应用中实现自定义缓存有所帮助。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Linux内存管理--系列文章柒——硬件架构
  • ELK集群搭建
  • 28个常用的损失函数介绍以及Python代码实现总结
  • React -- useState状态更新异步特性——导致获取值为旧值的问题
  • 前端工程化(01):10款自动化构建工具初识。
  • [GHCTF 2024 新生赛]ezzz_unserialize
  • 攻防世界 Web_python_template_injection(flask模版注入)
  • 网络安全应急响应信息收集利器-Eagle_Eye
  • Java中Collection集合和Map集合详解(进阶三)
  • sql注入之宽字节注入
  • WEB攻防-通用漏洞SQL注入-ACCESS一般注入与偏移注入
  • 【Scrapy】深入了解 Scrapy 中间件中的 process_spider_output 方法
  • Android 注解的语法原理和使用方法
  • 软设之代理模式
  • 【国内超大型智能算力中心建设白皮书 2024】_智算中心算力规划
  • 345-反转字符串中的元音字母
  • gcc介绍及安装
  • JavaScript 基本功--面试宝典
  • JavaScript 无符号位移运算符 三个大于号 的使用方法
  • JavaScript标准库系列——Math对象和Date对象(二)
  • Javascript基础之Array数组API
  • JDK 6和JDK 7中的substring()方法
  • jquery cookie
  • Laravel 实践之路: 数据库迁移与数据填充
  • Linux中的硬链接与软链接
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 前端面试题总结
  • 如何设计一个比特币钱包服务
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 使用Swoole加速Laravel(正式环境中)
  • 温故知新之javascript面向对象
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • 智能网联汽车信息安全
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • Hibernate主键生成策略及选择
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #NOIP 2014#Day.2 T3 解方程
  • (¥1011)-(一千零一拾一元整)输出
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (31)对象的克隆
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (TOJ2804)Even? Odd?
  • (规划)24届春招和25届暑假实习路线准备规划
  • (十八)SpringBoot之发送QQ邮件
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .md即markdown文件的基本常用编写语法
  • .Net Core中Quartz的使用方法
  • .NET程序员迈向卓越的必由之路
  • @Autowired和@Resource装配
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)