在现代应用开发中,缓存是提高系统性能和响应速度的关键技术之一。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应用中实现自定义缓存有所帮助。