`

spring boot使用 cache和redis,@Cacheable失效解决

 
阅读更多

先说一下如何配置spring boot+spring cache +redis

 

pom.xml

        <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.4.0.BUILD-SNAPSHOT</version>
	</parent>

	<!-- Add typical dependencies for a web application -->
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
	</dependencies>

 

application.property

 

server.contextPath=/a
server.port=8081


spring.redis.database=0  
spring.redis.host=127.0.0.1
spring.redis.port=6379  
spring.redis.password=  
spring.redis.pool.max-active=8  
spring.redis.pool.max-wait=-1  
spring.redis.pool.max-idle=8  
spring.redis.pool.min-idle=0  
spring.redis.timeout=0 

 

java配置

CacheConfig.java

 

import java.lang.reflect.Method;

import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.cache.interceptor.SimpleCacheResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
@EnableCaching
public class CacheConfig{

	@Bean
	public KeyGenerator keyGenerator() {
		return new KeyGenerator() {
			@Override
			public Object generate(Object target, Method method, Object... params) {
				StringBuilder sb = new StringBuilder();
				sb.append(target.getClass().getName());
				sb.append(method.getName());
				for (Object obj : params) {
					sb.append(obj.toString());
				}
				return sb.toString();
			}
		};
	}

	
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory){
        StringRedisTemplate template = new StringRedisTemplate(factory);
        setSerializer(template);//设置序列化工具
        template.afterPropertiesSet();
        return template;
    }
    

	@Bean 
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        //设置缓存过期时间 
        cacheManager.setDefaultExpiration(10000);
        return cacheManager;
    }
     private void setSerializer(RedisTemplate template){
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            template.setValueSerializer(jackson2JsonRedisSerializer);
     }
}

 

service层添加缓存

UserServiceImpl.java

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.sda.test.service.UserService;

@Service
public class UserServiceImpl implements UserService {

	@Cacheable(value = "aa", key = "'1'")
	public String getUser() {
		// 该打印用来判断是否重复进入方法内
		System.out.println("in");
		// 如果return null 不会缓存,必须有返回值
		return "1";
	}

}

 

写个controller调用

WebController.java

 

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.sda.test.service.UserService;

@RestController
public class WebController {

	@Autowired
	UserService userService;
	@RequestMapping("/s")
	public void name() {
		userService.getUser();
	}
}

 

浏览器输入http://127.0.0.1:8081/a/s

多次访问,查看控制台打印信息。会发现只有第一次访问会进入方法内,之后不再打印,因为直接读的redis缓存

 

 

遇到的问题

 

1.在RedisCacheConfig中引入了,引用有注解bean的bean,则cache不能用,举例来说

 

假如UserDAO.java  中有个方法用了缓存,如

UserDAO.java

        @Cacheable(value = "aa", key = "'1'")
	public String getUser() {
		return "1";
	}

 而UserServiceImpl.java中引用了了UserDAO

UserServiceImpl.java

@Resource
UserDAO userDAO;

 一旦CacheConfig.java中同时存在UserDAO和UserServiceImpl ,那么cache缓存就失效了

CacheConfig.java

@Configuration
@EnableCaching
public class CacheConfig{

	@Resource
	UserDAO userDAO;

	//UserService 中也有userDAO则cache失效。没有userDAO则可用
	@Autowired
	UserService userService;
	
	@Bean
	public KeyGenerator keyGenerator() {
		return new KeyGenerator() {
			@Override
			public Object generate(Object target, Method method, Object... params) {
				StringBuilder sb = new StringBuilder();
				sb.append(target.getClass().getName());
				sb.append(method.getName());
				for (Object obj : params) {
					sb.append(obj.toString());
				}
				return sb.toString();
			}
		};
	}

	
    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory){
        StringRedisTemplate template = new StringRedisTemplate(factory);
        setSerializer(template);//设置序列化工具
        template.afterPropertiesSet();
        return template;
    }
    

	@Bean 
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        //设置缓存过期时间 
        cacheManager.setDefaultExpiration(10000);
        return cacheManager;
    }
     private void setSerializer(RedisTemplate template){
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper om = new ObjectMapper();
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            jackson2JsonRedisSerializer.setObjectMapper(om);
            template.setValueSerializer(jackson2JsonRedisSerializer);
     }
}

 原因还不知道,应该跟aop有关,先记下来

分享到:
评论

相关推荐

    扩展spring boot cache实现redis一二级分布式缓存

    本篇文章将探讨如何扩展Spring Boot的缓存功能,实现基于Redis的一级和二级分布式缓存。Redis是一个高性能的键值存储系统,常用于实现分布式缓存。 一级缓存通常指的是应用程序内部的缓存,如Spring Cache或Guava ...

    spring-boot-cache.rar

    在这个名为 "spring-boot-cache.rar" 的压缩包中,我们很可能是找到了一个基于 Spring Boot 的小型项目,它展示了如何在 Spring Boot 应用中集成和使用缓存功能。下面我们将详细探讨 Spring Boot 缓存的相关知识点。...

    springboot1.x基于spring注解实现J2Cache两级缓存集成

    在本文中,我们将深入探讨如何在Spring Boot 1.x版本中使用Spring注解来实现J2Cache的两级缓存机制,其中包括一级缓存Ehcache和二级缓存Redis。通过这种方式,我们可以显著提高应用程序的性能,减少对数据库的依赖,...

    springboot使用springCache和不使用springCache的对比.zip

    本项目通过对比使用和不使用Spring Cache注解来探讨其作用和效果。 1. **@Cacheable**: 这个注解用于方法上,表示该方法的结果可以被缓存。当调用一个标记为@Cacheable的方法时,Spring会检查缓存中是否存在相同...

    spring-boot-cache:使用带有Spring Boot和Cache的简单演示项目进行项目

    在这个名为"spring-boot-cache"的项目中,我们将探讨如何在Spring Boot应用中集成并使用缓存。 首先,让我们了解Spring Boot的缓存注解。`@Cacheable`是核心注解之一,用于标记一个方法,当该方法被调用时,其结果...

    Springboot整合redis使用技巧.pdf

    综上所述,Spring Boot 整合 Redis 主要涉及 Spring Cache 接口的使用、自定义缓存策略、多 Cache Manager 实例的配置以及 Redis 使用的最佳实践。在实际开发中,理解这些知识点有助于构建高效、稳定和可扩展的缓存...

    springboot缓存一致性解决

    本文将深入探讨Spring Boot中如何处理和解决缓存一致性问题。 首先,我们需要理解缓存的一致性模型。常见的有三种:强一致性、最终一致性和读已写一致性(Read-Your-Writes Consistency)。在分布式系统中,强一致...

    springbt_guava_cache.7z

    本文将深入探讨如何在Spring Boot项目中集成并使用Guava Cache,以实现高效、灵活的缓存策略。 一、Spring Boot与Guava Cache简介 1. Spring Boot:作为Spring框架的微服务启动器,Spring Boot简化了Java应用的...

    springboot-01-cache.rar_browndl4_goldk4u_mill18b_springboot

    标题中的"springboot-01-cache.rar"表明这是一个关于Spring Boot缓存管理的项目压缩包。Spring Boot是Java开发的一款快速构建微服务的框架,它简化了Spring应用的初始搭建以及开发过程。"cache"部分则暗示我们这个...

    cache设置缓存数据,可直接运行

    它可能会使用Spring的`@Cacheable`、`@CacheEvict`、`@CachePut`等注解来实现缓存的存取和清除操作。通过这些注解,开发者可以在方法级别指定缓存的行为。 5. **CacheApplication.java**:这是Spring Boot应用的...

    SpringBootJPA + EhCache

    Spring Boot还支持使用`@Cacheable`、`@CacheEvict`等注解实现方法级的缓存管理。 3. **自定义缓存Key生成规则** 默认情况下,Spring Cache会基于方法参数的哈希值生成缓存Key,但有时这可能不满足需求。可以通过...

    Java缓存技术深入了解

    - Spring Boot框架集成缓存:通过注解如`@Cacheable`、`@CacheEvict`实现缓存操作,支持多种缓存库。 - Redis客户端Jedis、Lettuce:用于Java程序与Redis服务器交互,实现分布式缓存功能。 总结,Java缓存技术是...

Global site tag (gtag.js) - Google Analytics