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

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

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

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

2. 创建自定义缓存注解

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

java 复制代码
@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. 创建缓存切面

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

java 复制代码
@Aspect
@Component
public class CustomCacheAspect {

    @Resource
    private 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 可不配,不过会有提示,看着不爽。

java 复制代码
@Configuration
public class RedisConfig {
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(); // 或者使用JedisConnectionFactory等其他实现
    }

    @Bean
    public 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;
    }
}

这里使用的依赖

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

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

java 复制代码
    /**
     * 根据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注解:

java 复制代码
@SpringBootApplication
@EnableAspectJAutoProxy
public class AppStart  {

    public static void main(String[] args){
        SpringApplication.run(AppStart.class, args);
    }
}
7.测试
8.总结

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

相关推荐
毕设源码-赖学姐1 小时前
【开题答辩全过程】以 基于Android的校园快递互助APP为例,包含答辩的问题和答案
java·eclipse
damo011 小时前
stripe 支付对接
java·stripe
麦麦鸡腿堡2 小时前
Java的单例设计模式-饿汉式
java·开发语言·设计模式
假客套2 小时前
Request method ‘POST‘ not supported,问题分析和解决
java
傻童:CPU2 小时前
C语言需要掌握的基础知识点之前缀和
java·c语言·算法
爱吃山竹的大肚肚3 小时前
@Valid校验 -(Spring 默认不支持直接校验 List<@Valid Entity>,需用包装类或手动校验。)
java·开发语言
雨夜之寂3 小时前
mcp java实战 第一章-第一节-MCP协议简介.md
java·后端
摇滚侠3 小时前
Spring Boot 3零基础教程,WEB 开发 Thymeleaf 核心语法 笔记39
spring boot·笔记·后端·thymeleaf
艾德金的溪3 小时前
redis-7.4.6部署安装
前端·数据库·redis·缓存
皮皮林5513 小时前
蚂蚁又开源了一个顶级 Java 项目!
java