可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have Spring Redis working using spring-data-redis
with all default configuration likes localhost
default port
and so on.
Now I am trying to make the same configuration by configuring it in application.properties
file. But I cannot figure out how should I create beans exactly that my property values are read.
Redis Configuration File
@EnableRedisHttpSession
@Configuration
public class SpringSessionRedisConfiguration {
@Bean
JedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory();
}
@Autowired
@Bean
RedisCacheManager redisCacheManager(final StringRedisTemplate stringRedisTemplate) {
return new RedisCacheManager(stringRedisTemplate);
}
@Autowired
@Bean
StringRedisTemplate template(final RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
}
Standard Parameters in application.properties
spring.redis.sentinel.master=themaster
spring.redis.sentinel.nodes=192.168.188.231:26379
spring.redis.password=12345
What I tried,
- I can possibly use
@PropertySource
and then inject @Value
and get the values. But I don't want to do that as those properties are not defined by me but are from Spring.
- In this documentation Spring Redis Documentation, it only says that it can be configured using properties but doesn't show concrete example.
- I also went through Spring Data Redis API classes, and found that
RedisProperties
should help me, but still cannot figure out how exactly to tell Spring to read from properties file.
回答1:
You can use @PropertySource
to read options from application.properties or other property file you want. Please look PropertySource usage example and working example of usage spring-redis-cache. Or look at this small sample:
@Configuration
@PropertySource("application.properties")
public class SpringSessionRedisConfiguration {
@Value("${redis.hostname}")
private String redisHostName;
@Value("${redis.port}")
private int redisPort;
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Bean
JedisConnectionFactory jedisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(redisHostName);
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
RedisCacheManager cacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate());
return redisCacheManager;
}
}
In present time (december 2015) the spring.redis.sentinel options in application.properties
has limited support of RedisSentinelConfiguration
:
Please note that currently only Jedis and lettuce Lettuce support Redis Sentinel.
You may read more about this in official documentation.
回答2:
Upon looking deeper I found this, could it be what you are looking for?
# REDIS (RedisProperties)
spring.redis.database=0 # Database index used by the connection factory.
spring.redis.host=localhost # Redis server host.
spring.redis.password= # Login password of the redis server.
spring.redis.pool.max-active=8 # Max number of connections that can be allocated by the pool at a given time. Use a negative value for no limit.
spring.redis.pool.max-idle=8 # Max number of "idle" connections in the pool. Use a negative value to indicate an unlimited number of idle connections.
spring.redis.pool.max-wait=-1 # Maximum amount of time (in milliseconds) a connection allocation should block before throwing an exception when the pool is exhausted. Use a negative value to block indefinitely.
spring.redis.pool.min-idle=0 # Target for the minimum number of idle connections to maintain in the pool. This setting only has an effect if it is positive.
spring.redis.port=6379 # Redis server port.
spring.redis.sentinel.master= # Name of Redis server.
spring.redis.sentinel.nodes= # Comma-separated list of host:port pairs.
spring.redis.timeout=0 # Connection timeout in milliseconds.
Refernce:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html Searchterm Redis
From what I can see the values already exist and are defined as
spring.redis.host=localhost # Redis server host.
spring.redis.port=6379 # Redis server port.
if you want to create your own properties you can look at my previous post in this thread.
回答3:
I found this within the spring boot doc section 24 paragraph 7
@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {
private String username;
private InetAddress remoteAddress;
// ... getters and setters
}
Properties can then be modified via connection.property
Reference link: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties
回答4:
Here is an elegant solution to solve your issue :
@Configuration
@PropertySource(name="application", value="classpath:application.properties")
public class SpringSessionRedisConfiguration {
@Resource
ConfigurableEnvironment environment;
@Bean
public PropertiesPropertySource propertySource() {
return (PropertiesPropertySource) environment.getPropertySources().get("application");
}
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
return new JedisConnectionFactory(sentinelConfiguration(), poolConfiguration());
}
@Bean
public RedisSentinelConfiguration sentinelConfiguration() {
return new RedisSentinelConfiguration(propertySource());
}
@Bean
public JedisPoolConfig poolConfiguration() {
JedisPoolConfiguration config = new JedisPoolConfiguration();
// add your customized configuration if needed
return config;
}
@Bean
RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<Object, Object>();
redisTemplate.setConnectionFactory(jedisConnectionFactory());
return redisTemplate;
}
@Bean
RedisCacheManager cacheManager() {
return new RedisCacheManager(redisTemplate());
}
}
so, to resume :
- add a specific name for the @PropertySource
- inject a ConfigurableEnvironment instead of Environment
- get the PropertiesPropertySource in your ConfigurableEnvironment using the name you mentioned on your @PropertySource
- Use this PropertySource object to construct your RedisSentinelConfiguration object
- Don't forget to add 'spring.redis.sentinel.master' and 'spring.redis.sentinel.nodes' properties in you property file
Tested in my workspace,
Regards
回答5:
I think this what you are looking for
http://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot.html
回答6:
You can use the ResourcePropertySource to generate a PropertySource object.
PropertySource propertySource = new ResourcePropertySource("path/to/your/application.properties");
Then pass it to the constructor of the RedisSentinelConfiguration.
回答7:
Use @DirtiesContext(classMode = classmode.AFTER_CLASS)
at each test class. This will surely work for you.
回答8:
This works for me :
@Configuration
@EnableRedisRepositories
public class RedisConfig {
@Bean
public JedisConnectionFactory jedisConnectionFactory() {
RedisProperties properties = redisProperties();
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
configuration.setHostName(properties.getHost());
configuration.setPort(properties.getPort());
return new JedisConnectionFactory(configuration);
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
final RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(jedisConnectionFactory());
template.setValueSerializer(new GenericToStringSerializer<>(Object.class));
return template;
}
@Bean
@Primary
public RedisProperties redisProperties() {
return new RedisProperties();
}
}
and properties file :
spring.redis.host=localhost
spring.redis.port=6379
回答9:
@Autowired
private JedisConnectionFactory connectionFactory;
@Bean
JedisConnectionFactory connectionFactory() {
return connectionFactory
}