使用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应用中实现自定义缓存有所帮助。

相关推荐
我真会写代码7 分钟前
Redis核心特性详解:事务、发布订阅与数据删除淘汰策略
java·数据库·redis
IT 行者32 分钟前
LangChain4j 集成 Redis 向量存储:我踩过的坑和选型建议
java·人工智能·redis·后端
brucelee18632 分钟前
Spring Boot 测试最佳实践
spring boot·后端·log4j
一定要AK35 分钟前
Java流程控制
java·开发语言·笔记
tryCbest1 小时前
Java和Python开发项目部署简介
java·开发语言·python
huabiangaozhi1 小时前
postgresql链接详解
java
随风,奔跑1 小时前
Redis
数据库·redis·缓存
大阿明1 小时前
PostgreSQL常用时间函数与时间计算提取示例说明
java
小糯米6011 小时前
C++ 并查集
java·c++·算法
DROm RAPS1 小时前
十七:Spring Boot依赖 (2)-- spring-boot-starter-web 依赖详解
前端·spring boot·后端