Когда я интегрировал Redis с springboot2.x, я столкнулся с двумя переплетенными проблемами:
- При использовании файла yml пароль redis не может быть прочитан.
- Используйте свойствавместо файла, чтобы прочитать пароль, но отображается исключение.
Здесь я кратко объясню, что DefaultJedisClientConfiguration
является классом реализации JedisClientConfiguration
, а MutableJedisClientConfiguration
также является классом реализации,как статический внутренний класс в JedisConnectionFactory
.
Почему вызывается устаревший метод setTimeout()
в JedisConnectionFactory
?Более того, когда я использую файл .yml
для настройки ресурса redis, такой ошибки нет, то есть функция не будет вызываться, а когда используется файл .properties
, она будет вызываться.
/** @deprecated */
@Deprecated
public void setTimeout(int timeout) {
this.getMutableConfiguration().setReadTimeout(Duration.ofMillis((long)timeout));
this.getMutableConfiguration().setConnectTimeout(Duration.ofMillis((long)timeout));
}
// теперь Assert.state () будет выполняться.
private JedisConnectionFactory.MutableJedisClientConfiguration getMutableConfiguration() {
Assert.state(this.clientConfiguration instanceof JedisConnectionFactory.MutableJedisClientConfiguration, () -> {
return String.format("Client configuration must be instance of MutableJedisClientConfiguration but is %s", new Object[]{ClassUtils.getShortName(this.clientConfiguration.getClass())});
});
return (JedisConnectionFactory.MutableJedisClientConfiguration)this.clientConfiguration;
}
Когда мы передадим poolConfig
, JedisConnectionFactory
сгенерирует MutableJedisClientConfiguration
, но когда мы сами создаем JedisClientConfiguration
, генерируется DefaultJedisClientConfiguration
.
мой код конфигурации Java:
@Configuration
@PropertySource("classpath:config/redis.yml") // .yml
@EnableAutoConfiguration
class RedisConfig {
@Value("${spring.redis.password:123456}") // can not read password, should set default value
private String password;
@Bean
@ConfigurationProperties(prefix="spring.redis.pool")
public JedisPoolConfig jedisPoolConfig(){
return new JedisPoolConfig();
}
@Bean
@ConfigurationProperties(prefix="spring.redis")
public JedisConnectionFactory jedisConnectionFactory(){
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
JedisConnectionFactory jedisConnectionFactory = null;
JedisClientConfiguration.JedisClientConfigurationBuilder jedisClientConfiguration = JedisClientConfiguration.builder();
jedisConnectionFactory = new JedisConnectionFactory(redisStandaloneConfiguration,
jedisClientConfiguration.build()); // build() -> DefaultJedisClientConfiguration
return jedisConnectionFactory;
}
}
мой файл свойств:
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.name=localhost_redis
spring.redis.timeout=5000
spring.redis.password=123456
spring.redis.minIdle=1
spring.redis.maxTotal=5000
spring.redis.numTestsPerEvictionRun=100
spring.redis.timeBetweenEvictionRunsMillis=6000
spring.redis.testWhileIdle=true
spring.redis.testOnBorrow=true
spring.redis.testOnReturn=true
spring.redis.pool.max-idle=10
spring.redis.pool.max-wait=5000
файл yml:
spring:
redis:
dbIndex: 0
hostName: localhost
password: 123456
port: 6379
timeout: 5000
pool:
maxIdle: 8
minIdle: 0
maxActive: 8
maxWait: -1
ошибка:
Description:
Failed to bind properties under 'spring.redis' to org.springframework.data.redis.connection.jedis.JedisConnectionFactory:
Property: spring.redis.timeout
Value: 5000
Origin: "spring.redis.timeout" from property source "class path resource [config/redis.properties]"
Reason: Client configuration must be instance of MutableJedisClientConfiguration but is DefaultJedisClientConfiguration
Action:
Update your application's configuration