关于与其他函数具有相同类型和不同参数的弹簧豆的困惑

时间:2018-11-03 09:36:49

标签: java spring-boot

要自定义LettuceConnectionFactory,我创建了两个函数,它们具有相同的返回类型和不同的参数,一个是单节点配置,另一个是集群配置。代码如下:

@Component
@Configuration
public class RedisConfig {

    @Bean(name = "singleFactory")
    public LettuceConnectionFactory createSingleFactory(RedisSingleConfig redisSingleConfig){...}

    @Bean(name = "clusterFactory")
    public LettuceConnectionFactory createClusterFactory(RedisClusterConfig redisClusterConfig){...}

}

调用它们时,返回值(LettuceConnectionFactory)是另一个函数的参数。代码如下:

@Autowired
private RedisActivityClusterConfig testConfig;

@Autowired
private RedisItemConfig redisItemConfig;

@Autowired
private RedisConfig redisConfig;

@Autowired
private StringRedisTemplate redisTemplate;

@Test
public void test(){
    redisTemplate.setConnectionFactory(redisConfig.createClusterFactory(testConfig));
    ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
    System.out.println(valueOperations.get("test"));
}

但顺便说一下,春季将报告No qualifying bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' available: expected single matching bean but found 2: singleFactory,clusterFactory


添加的问题:

由于项目稍微复杂一些,因此有很多Redis单服务器A,B,C ...和群集服务器A,B,C ...,它们具有不同的ip,端口和池策略。我的原始想法是,通过将不同的redisConfig作为参数(例如RedisConfig_A,RedisConfig_B,RedisConfig_C(可通过参考资料中的redis.properties获取)来注入参数)来动态生成不同的LettuceConnectionFactories,然后使用这些LettuceConnectionFactories创建自定义的RedisTemplates。我的困惑是,这些objs:RedisConfig,LettuceConnectionFactories是否可以自动连线?我已经尝试了很多方法,但是没有用...

2 个答案:

答案 0 :(得分:1)

您需要创建自己的自定义RedisTemplate,否则默认帐户将尝试自动连接默认RedisConnectionFactory,从而导致错误。

@Component
@Configuration
public class RedisConfig {

    @Bean(name = "redisTemplateA")
    public RedisTemplate<String, Object> redisTemplateA(RedisClusterConfig redisClusterConfigA) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(createClusterFactoryA(redisClusterConfigA));
        return template;
    }

    @Primary
    @Bean(name = "singleFactoryA")
    public LettuceConnectionFactory createSingleFactoryA(RedisSingleConfig redisSingleConfigA){...}

    @Bean(name = "clusterFactoryA")
    public LettuceConnectionFactory createClusterFactoryA(RedisClusterConfig redisClusterConfigA){...}

    // other combinations as needed
}

然后在测试中使用此RedisTemplate。更多详细信息/示例here

额外,您无法进行动态配置传递,因为如上一个问题所述,您必须将LettuceConnectionFactory作为bean,而不能进行基本初始化。因此,您需要为每个配置定义LettuceConnectionFactories的所有组合,例如singleFactoryA(使用configA),clusterFactoryB(使用configB),然后只需使用所需的config + factory组合创建多个RedisTemplate。始终使用不同的Bean名称,这应该可以工作。

如果需要所有组合,则可以将所有这些RedisTemplate存储到某些Table中,其中键为配置类型(ABC和工厂类型(singlecluster),其值本身作为模板。 Table<ConfigType, FactoryType, RedisTemplate> redisTemplateTable,我只是假设ConfigTypeFactoryType作为您的自定义枚举类

答案 1 :(得分:0)

@Autowired注释告诉Spring注入点在哪里(即需要在哪里注入)。找到这样的注入点后,Spring会尝试找到相同类型的已配置bean(通过@Bean配置),如果找到了这样的bean,则会将其注入到注入点。

如果找到两个或更多这样的bean,它将抛出异常。为避免异常,我们必须使用@Qualifier批注。