在Spring应用程序中,通常会为每个Spring容器(或ApplicationContext)配置一个ConversionService实例。 Spring会选择该ConversionService,然后在框架需要执行类型转换时使用它。如果未向Spring注册任何ConversionService,则使用原始的基于PropertyEditor的系统。
例如,在项目中配置Redis、ElasticSearch时,通常这些服务都是集群部署的。在创建这些bean的实例时,需要将多个节点都配置到项目的properties文件中,通常都如下所示:
1 2
| 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中时,我们就需要自己将这些配置通过切割处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| @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;
@Bean(value = "jedisConnectionFactory") public JedisConnectionFactory createConnectionFactory() { JedisConnectionFactory jedisConnectionFactory = null; RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(); Set serviceRedisNodes = new HashSet<>(Arrays.asList(clusterNodes.split(","))); try { 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); 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 FastJson2JsonRedisSerializer<>(Object.class)); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new FastJson2JsonRedisSerializer<>(Object.class)); return redisTemplate; } }
|
这里创建Jedis实例的时候就是通过自己处理的参数。虽然三两行代码就能搞定,但也麻烦,直接将其注入为List岂不更好?
1 2
| @Value("${redis.cluster.nodes}") private List<String> clusterNodes;
|
当然,如果你直接这样注入是不行的,还需要Spring的一个类型转换器org.springframework.context.support.ConversionServiceFactoryBean。在applicationContext.xml中配置如下的bean:
1 2
| <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" />
|
此时便可以注入成功了。