Reputation: 2880
My application uses one "main" redis instance for things like session storage and cache but needs to talk to a separate "external" instance for other reasons. I am trying to determine the "best" ("most idiomatic"? "simplest"?) way to configure this in my Spring Boot application.
Ideally I'd just like to use the default auto-configuration for the main instance but as soon as I register a connection factory for the external instance the @ConditionalOnMissngBean({RedisConnectionFactory.class})
condition in LettuceConnectionConfiguration
becomes false and so the default instance isn't created. Looking at what else is going on in LettuceConnectionConfiguration
etc. I feel like I'd rather not manually configure it if I don't need to.
I could just not expose the "external" connection factory as a bean and only use it internally to create the beans that depend on it but, while that would be ok in my specific case, I'd like to understand if there's a better solution where both factories can be exposed.
Is there some way I can expose the second RedisConnectionFactory
without disabling the default one provided by auto configuration? Is there a clear "right way" to do this sort of thing?
Upvotes: 4
Views: 4241
Reputation: 7077
you must implement the BeanDefinitionRegistryPostProcessor to adjust the RedisConnectionFactory order
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;
@Component
public class MultipleRedisConnectionFactoryRegistrar implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
BeanDefinition bd1 = registry.getBeanDefinition("redisConnectionFactory");
if (bd1 != null) {
BeanDefinition bd = new RootBeanDefinition(ExternalRedisConnectionFactoryBean.class);
registry.registerBeanDefinition("externalRedisConnectionFactory", bd);
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
in ExternalRedisConnectionFactoryBean, you can create your own RedisConnectionFactory
import org.springframework.beans.factory.FactoryBean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
public class ExternalRedisConnectionFactoryBean implements FactoryBean<RedisConnectionFactory> {
@Override
public RedisConnectionFactory getObject() throws Exception {
//you can mannually create your external redis connection factory here
return null;
}
@Override
public Class<?> getObjectType() {
return RedisConnectionFactory.class;
}
}
if you want to use the multiple RedisConnectionFactory, you @Qualifier is the right choice, for example
@Autowired
@Qualifier("redisConnectionFactory")
private RedisConnectionFactory defaultRedisConnectionFactory;
@Autowired
@Qualifier("externalRedisConnectionFactory")
private RedisConnectionFactory externalRedisConnectionFactory;
Upvotes: 1