赞
踩
今天在做项目的时候需要使用SpringCache与Redis作为缓存
但是在,配置完成后,发现并没有达到目的
org.springframework.data.redis.RedisConnectionFailureException: Unable to
connect to Redis;
在排查完无法连接到Redis之后,以为项目能够正常运行,结果发现前端无法访问到数据
后台直接报错
Bean named**is expected to be of type**but
was actually of type ‘com.sun.proxy.$Proxy**
整合步骤:
①导入依赖
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- spring2.X集成redis所需common-pool2-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.6.0</version>
</dependency>
②application.properties配置文件
spring.redis.host=192.168.145.13
spring.redis.port=6379
spring.redis.database= 0
spring.redis.timeout=1800000
spring.redis.lettuce.pool.max-active=20
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
③Redis配置类【自定义key规则、缓存规则、转换问题(序列化)】
RedisConfig:
/** * @author 夏末 * @description TODO * @date 2022/10/1 10:11 */ @Configuration @EnableCaching public class RedisConfig { /** * 自定义key规则 * @return */ @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(); } }; } /** * 设置RedisTemplate规则 * @param redisConnectionFactory * @return */ @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); //解决查询缓存转换异常的问题 ObjectMapper om = new ObjectMapper(); // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); //序列号key value redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * 设置CacheManager缓存规则 * @param factory * @return */ @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisSerializer<String> redisSerializer = new StringRedisSerializer(); 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); // 配置序列化(解决乱码的问题),过期时间600秒 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofSeconds(600)) .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); return cacheManager; } }
④在service的对应实现类中添加相应注解
/** * 根据id查询子数据列表 * @param id * @return */ @Override @Cacheable(value = "dict",keyGenerator = "keyGenerator") public List<Dict> findChildData(Long id) { QueryWrapper<Dict> wrapper = new QueryWrapper<>(); wrapper.eq("parent_id", id); List<Dict> dicts = dictMapper.selectList(wrapper); for(Dict dict : dicts){ Long dictId = dict.getId(); dict.setHasChildren(hasChild(dictId)); } return dicts; }
/**
* 导入数据
* allEntries = true: 方法调用后清空所有缓存
*/
@Override
@CacheEvict(value = "dict", allEntries=true)
public void importDictData(MultipartFile file) {
try{
EasyExcel.read(file.getInputStream(), DictEeVo.class, new DictListener(dictMapper))
.sheet().doRead();
} catch (IOException e) {
e.printStackTrace();
}
}
⑤在启动类上开启扫描(扫描RedisConfig配置类)
@SpringBootApplication
@EnableSwagger2
@ComponentScan(basePackages = {"com.zi"})
public class ServiceCmnApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceCmnApplication.class);
}
}
①配置文件端口配错
②远程Redis的保护模式打开了
"修改redis.conf文件",将protected-mode配置设置为no
③bind绑定问题
"redis.conf文件",bind设置为了只允许本机访问。
将该行注释,或者将项目运行的服务器地址配置上去
④设置了访问密码
"redis.conf文件",在配置文件中将密码去掉或者在SpringBoot的application.yml中添加正确密码
①检查对应注解的value值是否正确
如:
Redis配置类的键生成器:
对应注解上的value值是否为类名首字母小写
②是否在配置类上开启注解,是否将配置类作为Bean交给Spring管理
@Configuration
@EnableCaching
public class RedisConfig {
...
}
③如果是多个模块的话,是否在启动类上添加了注解扫描
@SpringBootApplication
@EnableSwagger2
@ComponentScan(basePackages = {"com.zi"})
public class ServiceCmnApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceCmnApplication.class);
}
}
④如果是代码本身报错,查看是否是Idea自动导包导入错了
无法访问到远程Redis,是因为我开启了保护模式,将其改为no即可
无法实现缓存目的是因为我的项目是多个模块,但是在启动上没有添加注解扫描,同时将注解上面的value值对应错了,修改为keyGenerator即可
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。