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

cn.godmao.redis.config.RedisAutoConfig Maven / Gradle / Ivy

The newest version!
package cn.godmao.redis.config;

import cn.godmao.redis.*;
import cn.godmao.redis.annotation.Redis;
import cn.godmao.redis.aspect.CacheAspect;
import cn.godmao.redis.codec.EntityCodec;
import org.redisson.api.*;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.cache.Cache;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.CacheErrorHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class RedisAutoConfig extends CachingConfigurerSupport implements BeanPostProcessor {
    @Autowired
    private GenericApplicationContext applicationContext;

    @Autowired
    private RedissonClient redissonClient;

    @Nullable
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Class beanClass = AopUtils.getTargetClass(bean);
        Field[] fields = beanClass.getDeclaredFields();
        for (Field field : fields) {
            Redis annotation = field.getAnnotation(Redis.class);
            if (null == annotation) {
                continue;
            }

            String name = annotation.value();
            if (ObjectUtils.isEmpty(name)) {
                name = field.getName();
            }

            if (ObjectUtils.isEmpty(name)) {
                continue;
            }

            final String beanName_ = "redis_####_" + name;
            final Class type_ = field.getType();
            final Object object_;
            final Object bean_;


            if (this.applicationContext.containsBean(beanName_)) {
                bean_ = this.applicationContext.getBean(beanName_, type_);
            } else {
                ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                Type actualTypeArgument = actualTypeArguments[actualTypeArguments.length - 1];
                EntityCodec entityCodec = new EntityCodec(actualTypeArgument);

                if (type_.isAssignableFrom(RMap.class)) {
                    object_ = redissonClient.getMap(name, entityCodec);
                } else if (type_.isAssignableFrom(RList.class)) {
                    object_ = redissonClient.getList(name, entityCodec);
                } else if (type_.isAssignableFrom(RSet.class)) {
                    object_ = redissonClient.getSet(name, entityCodec);
                } else if (type_.isAssignableFrom(RKeys.class)) {
                    object_ = redissonClient.getKeys();
                } else {
                    System.err.println("未知类型" + type_ + "请添加");
                    continue;
                }

                ConfigurableListableBeanFactory beanFactory = this.applicationContext.getBeanFactory();
                bean_ = beanFactory.initializeBean(object_, beanName_);
                beanFactory.registerSingleton(beanName_, bean_);
            }

            try {
                field.setAccessible(true);
                field.set(bean, bean_);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }

        return bean;
    }

    @Bean
    public RedisLockTemplate lockTemplate(RedissonClient redissonClient) {
        return new RedisLockTemplate(redissonClient);
    }

//    @Bean
//    public ExecutorService executorService(RedissonClient redissonClient) {
//        return redissonClient.getExecutorService("WORK_REDIS_");
//    }

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
        return RedisConfig.redisTemplate(factory);
    }

    @Bean
    public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
        return RedisConfig.redisCacheManager(redisTemplate);
    }

    /**
     * redis消息监听器
     * 可以添加多个监听不同话题的redis监听器
     * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
     */
    @Bean
    @ConditionalOnBean(RedisListener.class)
    public  RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, RedisListener... listeners) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        // 订阅通道的地方
        for (RedisListener listener : listeners) {
            container.addMessageListener(listener, new ChannelTopic(listener.getKey()));
        }
        // 这个container 可以添加多个 messageLister
        return container;
    }


//    @Bean
//    @ConditionalOnBean(RedisMap.class)
//    public  RedisGroup redisGroup(RedisTemplate redisTemplate, RedisMap... redisMaps) {
//        Map> redisGroup = new HashMap<>();
//        for (RedisMap redisMap : redisMaps) {
//            redisMap.init(redisTemplate);
//            redisGroup.put(redisMap.getKey(), redisMap);
//        }
//        return new RedisGroup((Map) redisGroup);
//    }

    @Bean
    @ConditionalOnBean(AbstractRedisMap.class)
    public  Map> redisMaps(RedisTemplate redisTemplate, AbstractRedisMap... redisMaps) {
        Map> redisMaps_ = new HashMap<>();
        for (AbstractRedisMap redisMap : redisMaps) {
            redisMap.init(redisTemplate);
            redisMaps_.put(redisMap.getKey(), redisMap);
        }
        return redisMaps_;
    }

    @Bean
    public RedisGlobal redisGlobal(RedisTemplate redisTemplate) {
        return new RedisGlobal(redisTemplate);
    }


    @Bean
    @ConditionalOnBean(AbstractRedisValue.class)
    public  Map> redisValues(RedisTemplate redisTemplate, AbstractRedisValue... redisValues) {
        Map> redisValues_ = new HashMap<>();
        for (AbstractRedisValue redisValue : redisValues) {
            redisValue.init(redisTemplate);
            redisValues_.put(redisValue.getKey(), redisValue);
        }
        return redisValues_;
    }

    @Bean
    @Override
    public CacheErrorHandler errorHandler() {
        // 异常处理,当Redis发生异常时,打印日志,但是程序正常走

        return new CacheErrorHandler() {
            @Override
            public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
                System.err.printf("Redis occur handleCacheGetError:key -> [%s]", key);
                e.printStackTrace();
            }

            @Override
            public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
                System.err.printf("Redis occur handleCachePutError:key -> [%s];value -> [%s]", key, value);
                e.printStackTrace();
            }

            @Override
            public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
                System.err.printf("Redis occur handleCacheEvictError:key -> [%s]", key);
                e.printStackTrace();
            }

            @Override
            public void handleCacheClearError(RuntimeException e, Cache cache) {
                System.err.println("Redis occur handleCacheClearError:");
                e.printStackTrace();
            }
        };
    }


    @Bean
    @DependsOn({"redisTemplate"})
    public CacheAspect cacheAspect(RedisTemplate redisTemplate) {
        return new CacheAspect(redisTemplate);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy