Spring Redis - 从 application.properties 文件读取配置

Spring Redis - Read configuration from application.properties file

我有 Spring Redis 使用 spring-data-redis 使用所有默认配置,如 localhost 默认 port 等等。

现在我试图通过在 application.properties 文件中配置来进行相同的配置。但是我无法弄清楚我应该如何准确地创建 bean 来读取我的 属性 值。

Redis 配置文件

@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);
}
}

application.properties

中的标准参数

spring.redis.sentinel.master=themaster

spring.redis.sentinel.nodes=192.168.188.231:26379

spring.redis.password=12345

我试过的,

  1. 我可以使用 @PropertySource 然后注入 @Value 并获取值。但我不想这样做,因为这些属性不是我定义的,而是来自 Spring.
  2. 在这个文档Spring Redis Documentation中,只说可以使用属性进行配置,并没有给出具体的例子。
  3. 我也翻了Spring Data Redis API 类,发现RedisProperties应该对我有帮助,但还是搞不懂具体怎么说Spring 从属性文件中读取。

您可以使用 @PropertySource 从 application.properties 或您想要的其他 属性 文件中读取选项。请看PropertySource usage example and working example of usage spring-redis-cache。或者看看这个小样本:

@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;
    }
}

目前(2015 年 12 月spring.redis.sentinel application.properties 中的选项对 RedisSentinelConfiguration:

Please note that currently only Jedis and lettuce Lettuce support Redis Sentinel.

您可以在 official documentation 中阅读更多相关信息。

我在 spring 引导文档第 24 节第 7 段中找到了这个

@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {

    private String username;

    private InetAddress remoteAddress;

    // ... getters and setters

} 

然后可以通过 connection.property

修改属性

参考link:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties

深入了解后我发现了这一点,这可能是您要找的东西吗?

# 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. 

参考:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html Searchterm Redis

据我所知,这些值已经存在并定义为

spring.redis.host=localhost # Redis server host.
spring.redis.port=6379 # Redis server port.

如果你想创建自己的属性,你可以查看我之前在这个线程中的 post。

我想这就是你要找的 http://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot.html

您可以使用 ResourcePropertySource 生成 PropertySource 对象。

PropertySource propertySource = new ResourcePropertySource("path/to/your/application.properties");

然后传递给RedisSentinelConfiguration的构造函数。

@Autowired
private JedisConnectionFactory connectionFactory;

@Bean
JedisConnectionFactory connectionFactory() {
    return connectionFactory
}

这里有一个优雅的解决方案来解决您的问题:

@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());
    }

}

所以,继续:

  • 为@PropertySource 添加特定名称
  • 注入 ConfigurableEnvironment 而不是 Environment
  • 使用您在@PropertySource 中提到的名称在 ConfigurableEnvironment 中获取 PropertiesPropertySource
  • 使用此 PropertySource 对象构建您的 RedisSentinelConfiguration 对象
  • 不要忘记在 属性 文件中添加 'spring.redis.sentinel.master' 和 'spring.redis.sentinel.nodes' 属性

在我的工作区测试过, 此致

在每个测试 class 中使用 @DirtiesContext(classMode = classmode.AFTER_CLASS)。这一定对你有用。

这对我有用:

@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();
    }

}

和属性文件:

spring.redis.host=localhost
spring.redis.port=6379