我在Spring Boot项目中具有以下配置。
@SpringBootApplication
@EnableTransactionManagement
@EnableCaching
@EnableScheduling
@EnableAsync
public class Application {
String redisHost = "localhost";
int redisPort = 6379;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(redisHost);
factory.setPort(redisPort);
factory.setUsePool(true);
return factory;
}
@Bean
RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
return redisTemplate;
}
@Bean
public CacheManager cacheManager() {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate());
return cacheManager;
}
}
而且我对pom也有以下的maven依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
我在定义的端口上的本地计算机上运行单独的Redis服务器。同样在我的服务类中,我有@ Cacheable,@ CachePut之类的注释来支持缓存。
我可以启动Spring Boot应用程序而不会出错,CRUD操作也可以。但是似乎它没有使用定义的redis缓存。我使用了“ redi桌面管理器”浏览工具,找不到有关redis的任何数据。我也尝试通过redis cli命令'monitor'来监视Redis服务器,但在监视器上看不到任何更改。
因此,我认为Redis缓存在Spring Boot应用程序上仍然无法正常工作。有人可以帮我解决这个问题吗?
我正在使用Spring Boot 1.4.2.RELEASE
谢谢!
鉴于您使用的是Spring Boot,不需要进行很多Redis配置,因为Spring Boot为Redis提供了[auto-configuration”支持,既是data source也是一个caching provider。
您也不确定使用什么版本的[[Spring Boot(例如1.5.0.RC1
)来运行您的应用程序,或者您的应用程序的类路径上是否有任何application.properties
,这可能会有所不同您明确指定了spring.cache.type
(例如,设置为“ redis”以外的其他值)。
Spring Cache
@Configuration
类有多大错误。但是,未显式设置cacheManager.setUsePrefix(true)
似乎确实是一个问题。当我设置此RedisCacheManager
属性('usePrefix`)时,一切都会按预期进行。我不是(Spring Data)Redis专家,所以我不确定为什么需要这样做。但是,我的测试配置基于Spring Boot's
"auto-configuration" support for Redis caching以及您的@Configuration
“ Application”类,如上所示。并且,因为您可以消除大部分显式配置,并且还使用Spring Boot's
"auto-configuration" support for Redis作为数据源,所以我在测试类中添加了"AutoRedisConfiguration"
@Configuration
类。即您可以使用它来配置Redis,而不是我的其他@Configuration
类("CustomRedisConfiguration"
),它使用您的配置+ fix。这里是完整的测试示例.../*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.spring.cache;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.PostConstruct;
import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.MethodSorters;
import org.spring.cache.CachingWithRedisIntegrationTest.CachingWithRedisConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.Assert;
/**
* Integration tests testing Spring's Cache Abstraction using Spring Data Redis auto-configured with Spring Boot.
*
* To run this test, first start a Redis Server on localhost listening on the default port, 6379.
*
* @author John Blum
* @see org.junit.Test
* @since 1.0.0
*/
@RunWith(SpringRunner.class)
@ActiveProfiles("auto")
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@ContextConfiguration(classes = CachingWithRedisConfiguration.class)
@SuppressWarnings("unused")
public class CachingWithRedisIntegrationTest {
protected static final int REDIS_PORT = 6379;
protected static final String REDIS_HOST = "localhost";
private AtomicBoolean setup = new AtomicBoolean(false);
@Autowired
private MathService mathService;
@Autowired(required = false)
private RedisTemplate<Object, Object> redisTemplate;
@Before
public void setup() {
if (redisTemplate != null && !setup.getAndSet(true)) {
redisTemplate.delete(Arrays.asList(0L, 1L, 2L, 4L, 8L));
}
}
@Test
public void firstCacheMisses() {
assertThat(mathService.factorial(0L)).isEqualTo(1L);
assertThat(mathService.wasCacheMiss()).isTrue();
assertThat(mathService.factorial(1L)).isEqualTo(1L);
assertThat(mathService.wasCacheMiss()).isTrue();
assertThat(mathService.factorial(2L)).isEqualTo(2L);
assertThat(mathService.wasCacheMiss()).isTrue();
assertThat(mathService.factorial(4L)).isEqualTo(24L);
assertThat(mathService.wasCacheMiss()).isTrue();
assertThat(mathService.factorial(8L)).isEqualTo(40320L);
assertThat(mathService.wasCacheMiss()).isTrue();
}
@Test
public void thenCacheHits() {
assertThat(mathService.factorial(0L)).isEqualTo(1L);
assertThat(mathService.wasCacheMiss()).isFalse();
assertThat(mathService.factorial(1L)).isEqualTo(1L);
assertThat(mathService.wasCacheMiss()).isFalse();
assertThat(mathService.factorial(2L)).isEqualTo(2L);
assertThat(mathService.wasCacheMiss()).isFalse();
assertThat(mathService.factorial(4L)).isEqualTo(24L);
assertThat(mathService.wasCacheMiss()).isFalse();
assertThat(mathService.factorial(8L)).isEqualTo(40320L);
assertThat(mathService.wasCacheMiss()).isFalse();
}
interface MathService {
boolean wasCacheMiss();
long factorial(long number);
}
@EnableCaching
@SpringBootConfiguration
@Import({ AutoRedisConfiguration.class, CustomRedisConfiguration.class })
static class CachingWithRedisConfiguration {
@Bean
MathService mathService() {
return new MathService() {
private final AtomicBoolean cacheMiss = new AtomicBoolean(false);
@Override
public boolean wasCacheMiss() {
return cacheMiss.getAndSet(false);
}
@Override
@Cacheable(cacheNames = "Factorials")
public long factorial(long number) {
cacheMiss.set(true);
Assert.isTrue(number >= 0L, String.format("Number [%d] must be greater than equal to 0", number));
if (number <= 2L) {
return (number < 2L ? 1L : 2L);
}
long result = number;
while (--number > 1) {
result *= number;
}
return result;
}
};
}
@Bean
@Profile("none")
CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
}
@Profile("auto")
@EnableAutoConfiguration
@SpringBootConfiguration
static class AutoRedisConfiguration {
@PostConstruct
public void afterPropertiesSet() {
System.out.println("AUTO");
}
@Bean
static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer =
new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setProperties(redisProperties());
return propertySourcesPlaceholderConfigurer;
}
static Properties redisProperties() {
Properties redisProperties = new Properties();
redisProperties.setProperty("spring.cache.type", "redis");
redisProperties.setProperty("spring.redis.host", REDIS_HOST);
redisProperties.setProperty("spring.redis.port", String.valueOf(REDIS_PORT));
return redisProperties;
}
}
@Profile("custom")
@SpringBootConfiguration
static class CustomRedisConfiguration {
@PostConstruct
public void afterPropertiesSet() {
System.out.println("CUSTOM");
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(REDIS_HOST);
factory.setPort(REDIS_PORT);
factory.setUsePool(true);
return factory;
}
@Bean
RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
return redisTemplate;
}
@Bean
CacheManager cacheManager() {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate());
cacheManager.setUsePrefix(true); // THIS IS NEEDED!
return cacheManager;
}
}
}
希望这会有所帮助!干杯,约翰
spring.cache.type = redisredis.host.url =redis.host.port =
就是这样!
如果使用的是AWS Elasticache,并且已经检查了传输中的加密,那么您需要添加一个RedisConfiguration文件以将ssl设置为true。
Spring Boot 2.0现在使用LettuceConnectionFactory。
要做上述事情,只需添加一个类并用@Configuration批注将其标记并添加以下bean
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
configuration.setHostName(redisHost);
configuration.setPort(redisPort);
return new LettuceConnectionFactory(configuration, LettuceClientConfiguration.builder().useSsl().disablePeerVerification().build());
}
keys *