Путаница по поводу пружинных бобов с тем же типом и другим параметром, что и параметр другой функции - PullRequest
0 голосов
/ 03 ноября 2018

Чтобы настроить 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, port и pool. Моя оригинальная идея заключается в том, чтобы динамически генерировать разные LettuceConnectionFactories путем внедрения в разные redisConfig в качестве параметров, таких как RedisConfig_A, RedisConfig_B, RedisConfig_C (конфиги можно получить с помощью redis.properties в Resources), а затем использовать эти LettuceConnectionFactories для создания настроенных RedisTemplates. Мое замешательство заключается в том, могут ли эти объекты: RedisConfig, LettuceConnectionFactories быть автоматически подключены? Я пробовал много способов, но это не работает ...

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Аннотация @Autowired сообщает Spring, где находится точка впрыска (т. Е. Где необходимо выполнить впрыск). При нахождении такой точки ввода Spring пытается найти настроенный компонент (настроенный с помощью @Bean) того же типа, если он находит такой компонент, он вводит его в точку внедрения.

Если он найдет два или более таких бинов, он выдаст исключение. Чтобы избежать исключения, мы должны использовать аннотацию @Qualifier.

0 голосов
/ 03 ноября 2018

Вам необходимо создать свой собственный пользовательский 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 в своих тестах. Подробнее / примеры здесь

Extra вы не можете передавать динамическую конфигурацию, поскольку, как говорилось в предыдущем вопросе, вы должны иметь LettuceConnectionFactory в качестве bean-компонентов, а не базовой инициализации. Поэтому вам необходимо определить все комбинации LettuceConnectionFactories для каждой конфигурации, например, singleFactoryA (используя configA), clusterFactoryB (используя configB), затем просто создайте несколько RedisTemplate с любой комбинацией config + factory, которая вам нужна. Всегда используйте разные имена бинов, это должно работать.

Если вам потребуются все комбинации, вы можете сохранить все эти RedisTemplate в некотором Table, где ключи будут иметь тип конфигурации (A, B, C) и тип фабрики ( single, cluster) со значениями в качестве самих шаблонов. Table<ConfigType, FactoryType, RedisTemplate> redisTemplateTable, где я только что предположил ConfigType & FactoryType в качестве пользовательских классов

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...