springboot 自定义注解 redis
时间: 2025-01-19 10:51:52 浏览: 41
### 创建和使用自定义注解与Redis集成
#### 自定义注解的创建
为了实现特定的功能需求,在Spring Boot项目中可以创建自定义注解来简化开发流程并提高代码可读性。通过Java内置的支持,能够轻松地定义新的元数据标签。
```java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheOperation {
String key() default "";
}
```
此段代码展示了如何声明一个新的名为`CacheOperation`的注解,它可以在方法级别上应用,并且会在运行时被处理[^1]。
#### Redis缓存管理器配置
为了让自定义注解生效并与Redis交互,需要配置相应的缓存管理组件。这通常涉及到引入必要的依赖项以及编写适当的Bean定义。
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
```
接着是在应用程序上下文中注册一个基于Redis的缓存解析器实例:
```java
@Configuration
@EnableCaching
public class AppConfig {
private final RedisConnectionFactory connectionFactory;
public AppConfig(RedisConnectionFactory connectionFactory) {
this.connectionFactory = connectionFactory;
}
@Bean
public CacheManager cacheManager() {
return new RedisCacheManager(
RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory),
RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1))
);
}
}
```
上述配置片段说明了怎样利用`RedisCacheManager`作为全局缓存策略的一部分,同时设置了默认条目的过期时间为一小时[^2]。
#### 实现切面逻辑
最后一步是要让带有自定义注解的方法自动触发对应的缓存行为。为此,可以通过AOP(面向方面编程)技术拦截这些调用点,并执行实际的数据存储或检索动作。
```java
@Aspect
@Component
@Slf4j
public class CachingAspect {
@Autowired
private CacheManager cacheManager;
@Around("@annotation(cacheOp)")
public Object manageCache(final ProceedingJoinPoint joinPoint, CacheOperation cacheOp) throws Throwable {
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
log.info("Invoking method {} with arguments {}", methodName, args);
// Generate unique key based on method name and parameters
String generatedKey = generateUniqueKey(methodName, args);
if (StringUtils.hasText(cacheOp.key())) {
generatedKey += ":" + cacheOp.key();
}
Cache.ValueMatcher valueMatcher = null; // Define matcher logic here as needed
ValueOperations<String, String> opsForValue = template.opsForValue();
try {
// Try fetching from cache first
String cachedResult = opsForValue.get(generatedKey);
if (cachedResult != null && !cachedResult.isEmpty()) {
log.debug("Returning cached result for key '{}'", generatedKey);
return objectMapper.readValue(cachedResult, Object.class); // Deserialize object back
} else {
// If not found in cache, proceed to execute target method
Object result = joinPoint.proceed();
// Store computed results into Redis after successful execution
opsForValue.set(generatedKey, objectMapper.writeValueAsString(result));
return result;
}
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e.getCause());
}
}
private static String generateUniqueKey(String methodName, List<Object> params){
StringBuilder sb = new StringBuilder(methodName).append(":");
for(Object param : params){
sb.append(param.toString()).append("_");
}
return sb.toString();
}
}
```
这段程序实现了当任何地方使用了`@CacheOperation`标记的方法被执行时,都会先尝试从Redis获取已有的计算结果;如果没有命中,则继续正常调用业务逻辑并将返回值保存下来以便将来重复访问时可以直接提供给客户端[^3]。
阅读全文
相关推荐



















