RedisMessageListenerContainer是Spring Data Redis提供的一个容器类,为Redis监听器提供异步处理能力,处理低级别消息、转换Redis的消息通道,它通常与MessageListenerAdapter和自定义的消息监听器一起使用。
RedisMessageListenerContainer_4">一、RedisMessageListenerContainer容器类初始化
private void initMessageListenerContainer() {this.messageListenerContainer = new RedisMessageListenerContainer();this.messageListenerContainer.setConnectionFactory(((RedisTemplate<?, ?>) redisOps).getConnectionFactory());this.messageListenerContainer.afterPropertiesSet();this.messageListenerContainer.start();}
org.springframework.data.redis.core.RedisKeyValueAdapter适配器类会在构造函数或afterPropertiesSet回调方法中调用initMessageListenerContainer初始化方法。
二、RedisKeyValueAdapter适配器类
private static AbstractBeanDefinition createRedisKeyValueAdapter(RepositoryConfigurationSource configuration) {BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(RedisKeyValueAdapter.class) //.addConstructorArgReference(configuration.getRequiredAttribute("redisTemplateRef", String.class)) //.addConstructorArgReference(REDIS_CONVERTER_BEAN_NAME) //.addPropertyValue("enableKeyspaceEvents",configuration.getRequiredAttribute("enableKeyspaceEvents", EnableKeyspaceEvents.class)) //.addPropertyValue("keyspaceNotificationsConfigParameter",configuration.getAttribute("keyspaceNotificationsConfigParameter", String.class).orElse("")) //.addPropertyValue("shadowCopy", configuration.getRequiredAttribute("shadowCopy", ShadowCopy.class));configuration.getAttribute("messageListenerContainerRef").ifPresent(it -> builder.addPropertyReference("messageListenerContainer", it));return builder.getBeanDefinition();}
org.springframework.data.redis.repository.configuration.RedisRepositoryConfigurationExtension类会在registerBeansForRoot方法中将RedisKeyValueAdapter对象定义成AbstractBeanDefinition对象注册到BeanDefinitionRegistry中。
三、RedisRepositoryConfigurationExtension对象初始化
@Overrideprotected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {return new RedisRepositoryConfigurationExtension();}
RedisRepositoriesRegistrar类中定义类RedisRepositoryConfigurationExtension对象的实例化方法,并且被RedisRepositoriesRegistrar的抽象父类AbstractRepositoryConfigurationSourceSupport中的registerBeanDefinitions方法调用。
AbstractRepositoryConfigurationSourceSupport#registerBeanDefinitions方法:
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,BeanNameGenerator importBeanNameGenerator) {RepositoryConfigurationDelegate delegate = new RepositoryConfigurationDelegate(getConfigurationSource(registry, importBeanNameGenerator), this.resourceLoader, this.environment);delegate.registerRepositoriesIn(registry, getRepositoryConfigurationExtension());
}
上述registerBeanDefinitions方法是被ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsFromRegistrars方法所调用,此类是spring初始化bean及相关类的核心。
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {registrars.forEach((registrar, metadata) ->registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));}
RedisMessageListenerContainer_73">四、RedisMessageListenerContainer容器初始化相关默认值
class RedisRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport {@Overrideprotected Class<? extends Annotation> getAnnotation() {return EnableRedisRepositories.class;}@Overrideprotected Class<?> getConfiguration() {return EnableRedisRepositoriesConfiguration.class;}@Overrideprotected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {return new RedisRepositoryConfigurationExtension();}@EnableRedisRepositoriesprivate static final class EnableRedisRepositoriesConfiguration {}}
RedisRepositoriesRegistrar类是RedisMessageListenerContainer监听器容器类的初始化起点类,会读取@EnableRedisRepositories注解的属性配置,如果项目中未显式使用此注解则读取默认值,如:redisTemplateRef属性默认引用别名为redisTemplate的模板类。
五、如何开启Spring Data Redis Repositories仓储
- 方案一:
/**
* 通过在配置类上添加次注解
**/
@EnableRedisRepositories
- 方案二:
/**
* 通过spring.data.redis.repositories.enabled配置开关
**/
@AutoConfiguration(after = RedisAutoConfiguration.class)
@ConditionalOnClass(EnableRedisRepositories.class)
@ConditionalOnBean(RedisConnectionFactory.class)
@ConditionalOnProperty(prefix = "spring.data.redis.repositories", name = "enabled", havingValue = "true",matchIfMissing = true)
@ConditionalOnMissingBean(RedisRepositoryFactoryBean.class)
@Import(RedisRepositoriesRegistrar.class)
public class RedisRepositoriesAutoConfiguration {}
开源SDK:https://github.com/mingyang66/spring-parent