在Spring应用程序中,通常会为每个Spring容器(或ApplicationContext)配置一个ConversionService实例。 Spring会选择该ConversionService,然后在框架需要执行类型转换时使用它。如果未向Spring注册任何ConversionService,则使用原始的基于PropertyEditor的系统。例如,在项目中配置Redis、ElasticSearch时,通常这些服务都是集群部署的。在创建这些bean的实例时,需要将多个节点都配置到项目的properties文件中,通常都如下所示:
spring.elasticsearch.rest.ip-address=10.254.5.102:9200,10.254.5.107:9201,10.254.5.108:9201 redis.cluster.nodes=10.10.100.197:7000,10.10.100.197:7001,10.10.100.197:7002,10.10.100.197:7003,10.10.100.197:7004,10.10.100.197:7005
properties本身是k-v对,解析出来也都是String类型,那么在我们将这些配置注入到XXXConfig中时,我们就需要自己将这些配置通过切割处理:
@Configuration
@PropertySource(value = {"classpath:application.properties"})
public class RedisConfig {
private final Logger logger = LoggerFactory.getLogger(RedisConfig.class);
@Value("${redis.cluster.nodes}")
private String clusterNodes;
@Value("${redis.password}")
private String password;
@Value("${redis.pool.max-active}")
private Integer maxTotal;
@Value("${redis.pool.max-idle}")
private Integer maxIdle;
@Value("${redis.pool.min-idle}")
private Integer minIdle;
@Value("${redis.pool.max-wait}")
private Integer maxWaitMillis;
@Value("${redis.testOnBorrow:true}")
private boolean testOnBorrow;
/**
* 创建连接工厂
*
* @return
*/
@Bean(value = "jedisConnectionFactory")
public JedisConnectionFactory createConnectionFactory() {
JedisConnectionFactory jedisConnectionFactory = null;
// 集群模式
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
// 加载服务器集群节点
Set serviceRedisNodes = new HashSet<>(Arrays.asList(clusterNodes.split(",")));
try {
// 转换成Redis点节
Set clusterNodes = new HashSet<>(serviceRedisNodes.size());
for (String node : serviceRedisNodes) {
String[] ipAndPort = StringUtils.split(node, ":");
String ip = ipAndPort[0];
int port = Integer.parseInt(ipAndPort[1]);
clusterNodes.add(new RedisNode(ip, port));
}
redisClusterConfiguration.setClusterNodes(clusterNodes);
// Redis 连接池配置
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(maxIdle);
poolConfig.setMaxTotal(maxTotal);
poolConfig.setMinIdle(minIdle);
poolConfig.setMaxWaitMillis(maxWaitMillis);
poolConfig.setTestOnBorrow(testOnBorrow);
// 创建连接工厂
jedisConnectionFactory = new JedisConnectionFactory(redisClusterConfiguration, poolConfig);
// 设置数据库
jedisConnectionFactory.setDatabase(0);
// 设置密码
jedisConnectionFactory.setPassword(password);
} catch (Exception e) {
logger.error("创建Redis连接工厂错误:{}", e);
}
return jedisConnectionFactory;
}
@Bean(value = "redisTemplate")
public RedisTemplate<String, Object> registerRedisTemplate(JedisConnectionFactory jedisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(jedisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
//redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setValueSerializer(new FastJson2JsonRedisSerializer<>(Object.class));
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashValueSerializer(new FastJson2JsonRedisSerializer<>(Object.class));
return redisTemplate;
}
}
这里创建Jedis实例的时候就是通过自己处理的参数。虽然三两行代码就能搞定,但也麻烦,直接将其注入为List岂不更好?
@Value("${redis.cluster.nodes}")
private List<String> clusterNodes;
当然,如果你直接这样注入是不行的,还需要Spring的一个类型转换器org.springframework.context.support.ConversionServiceFactoryBean。在applicationContext.xml中配置如下的bean:
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean" />
此时便可以注入成功了。






