All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.emily.infrastructure.redis.repository.RedisDbRepositoryConfigurationExtension Maven / Gradle / Ivy

The newest version!
package com.emily.infrastructure.redis.repository;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.*;
import org.springframework.data.keyvalue.repository.config.KeyValueRepositoryConfigurationExtension;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.convert.MappingConfiguration;
import org.springframework.data.redis.core.convert.MappingRedisConverter;
import org.springframework.data.redis.core.convert.RedisCustomConversions;
import org.springframework.data.redis.core.mapping.RedisMappingContext;
import org.springframework.data.repository.config.RepositoryConfigurationSource;
import org.springframework.util.StringUtils;

import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Collections;

/**
 * RedisRepositoryConfigurationExtension for Redis
 *
 * @author :  Emily
 * @since :  2024/7/8 上午20:00
 */
public class RedisDbRepositoryConfigurationExtension extends KeyValueRepositoryConfigurationExtension {

    private static final String REDIS_CONVERTER_BEAN_NAME = "redisConverter";
    private static final String REDIS_REFERENCE_RESOLVER_BEAN_NAME = "redisReferenceResolver";
    private static final String REDIS_ADAPTER_BEAN_NAME = "redisKeyValueAdapter";
    private static final String REDIS_CUSTOM_CONVERSIONS_BEAN_NAME = "redisCustomConversions";
    private static final String REDIS_MAPPING_CONFIG_BEAN_NAME = "redisMappingConfiguration";

    @Override
    public String getModuleName() {
        return "Redis";
    }

    @Override
    protected String getModulePrefix() {
        return this.getModuleIdentifier();
    }

    @Override
    protected String getDefaultKeyValueTemplateRef() {
        return "redisKeyValueTemplate";
    }

    @Override
    public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource configuration) {

        String redisTemplateRef = configuration.getAttribute("redisTemplateRef").get();

        if (!StringUtils.hasText(redisTemplateRef)) {
            throw new IllegalStateException(
                    "@EnableRedisRepositories(redisTemplateRef = … ) must be configured to a non empty value");
        }

        // Mapping config

        String mappingConfigBeanName = BeanDefinitionReaderUtils.uniqueBeanName(REDIS_MAPPING_CONFIG_BEAN_NAME, registry);
        String indexConfigurationBeanName = BeanDefinitionReaderUtils.uniqueBeanName("redisIndexConfiguration", registry);
        String keyspaceConfigurationBeanName = BeanDefinitionReaderUtils.uniqueBeanName("redisKeyspaceConfiguration",
                registry);

        registerIfNotAlreadyRegistered(() -> BeanDefinitionBuilder
                .rootBeanDefinition(configuration.getRequiredAttribute("indexConfiguration", Class.class)) //
                .setRole(BeanDefinition.ROLE_INFRASTRUCTURE) //
                .getBeanDefinition(), registry, indexConfigurationBeanName, configuration.getSource());

        registerIfNotAlreadyRegistered(() -> BeanDefinitionBuilder
                .rootBeanDefinition(configuration.getRequiredAttribute("keyspaceConfiguration", Class.class)) //
                .setRole(BeanDefinition.ROLE_INFRASTRUCTURE) //
                .getBeanDefinition(), registry, keyspaceConfigurationBeanName, configuration.getSource());

        registerIfNotAlreadyRegistered(
                () -> createMappingConfigBeanDef(indexConfigurationBeanName, keyspaceConfigurationBeanName), registry,
                mappingConfigBeanName, configuration.getSource());

        registerIfNotAlreadyRegistered(() -> createRedisMappingContext(mappingConfigBeanName), registry,
                MAPPING_CONTEXT_BEAN_NAME, configuration.getSource());

        // Register custom conversions
        registerIfNotAlreadyRegistered(() -> new RootBeanDefinition(RedisCustomConversions.class), registry,
                REDIS_CUSTOM_CONVERSIONS_BEAN_NAME, configuration.getSource());

        // Register referenceResolver
        registerIfNotAlreadyRegistered(() -> createRedisReferenceResolverDefinition(redisTemplateRef), registry,
                REDIS_REFERENCE_RESOLVER_BEAN_NAME, configuration.getSource());

        // Register converter
        registerIfNotAlreadyRegistered(() -> createRedisConverterDefinition(), registry, REDIS_CONVERTER_BEAN_NAME,
                configuration.getSource());

        registerIfNotAlreadyRegistered(() -> createRedisKeyValueAdapter(configuration), registry, REDIS_ADAPTER_BEAN_NAME,
                configuration.getSource());

        super.registerBeansForRoot(registry, configuration);
    }

    @Override
    protected AbstractBeanDefinition getDefaultKeyValueTemplateBeanDefinition(
            RepositoryConfigurationSource configurationSource) {

        return BeanDefinitionBuilder.rootBeanDefinition(RedisDbKeyValueTemplate.class) //
                .addConstructorArgReference(REDIS_ADAPTER_BEAN_NAME) //
                .addConstructorArgReference(MAPPING_CONTEXT_BEAN_NAME) //
                .getBeanDefinition();
    }

    @Override
    protected Collection> getIdentifyingAnnotations() {
        return Collections.singleton(RedisHash.class);
    }

    private static AbstractBeanDefinition createRedisKeyValueAdapter(RepositoryConfigurationSource configuration) {

        BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(RedisDbKeyValueAdapter.class) //
                .addConstructorArgReference(configuration.getRequiredAttribute("redisTemplateRef", String.class)) //
                .addConstructorArgReference(REDIS_CONVERTER_BEAN_NAME) //
                .addPropertyValue("enableKeyspaceEvents",
                        configuration.getRequiredAttribute("enableKeyspaceEvents", RedisDbKeyValueAdapter.EnableKeyspaceEvents.class)) //
                .addPropertyValue("keyspaceNotificationsConfigParameter",
                        configuration.getAttribute("keyspaceNotificationsConfigParameter", String.class).orElse("")) //
                .addPropertyValue("shadowCopy", configuration.getRequiredAttribute("shadowCopy", RedisDbKeyValueAdapter.ShadowCopy.class));

        configuration.getAttribute("messageListenerContainerRef")
                .ifPresent(it -> builder.addPropertyReference("messageListenerContainer", it));

        return builder.getBeanDefinition();
    }

    private static AbstractBeanDefinition createRedisReferenceResolverDefinition(String redisTemplateRef) {

        return BeanDefinitionBuilder.rootBeanDefinition("org.springframework.data.redis.core.convert.ReferenceResolverImpl") //
                .addConstructorArgReference(redisTemplateRef) //
                .getBeanDefinition();
    }

    private static AbstractBeanDefinition createRedisMappingContext(String mappingConfigRef) {

        return BeanDefinitionBuilder.rootBeanDefinition(RedisMappingContext.class) //
                .addConstructorArgReference(mappingConfigRef).getBeanDefinition();
    }

    private static AbstractBeanDefinition createMappingConfigBeanDef(String indexConfigRef, String keyspaceConfigRef) {

        return BeanDefinitionBuilder.genericBeanDefinition(MappingConfiguration.class) //
                .addConstructorArgReference(indexConfigRef) //
                .addConstructorArgReference(keyspaceConfigRef) //
                .getBeanDefinition();
    }

    private static AbstractBeanDefinition createRedisConverterDefinition() {

        return BeanDefinitionBuilder.rootBeanDefinition(MappingRedisConverter.class) //
                .addConstructorArgReference(MAPPING_CONTEXT_BEAN_NAME) //
                .addPropertyReference("referenceResolver", REDIS_REFERENCE_RESOLVER_BEAN_NAME) //
                .addPropertyReference("customConversions", REDIS_CUSTOM_CONVERSIONS_BEAN_NAME) //
                .getBeanDefinition();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy