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

com.ideaaedi.extspringcache.provider.ExtRedisCaffeineCacheManagerProvider Maven / Gradle / Ivy

There is a newer version: 3.0.2.GAMMA
Show newest version
package com.ideaaedi.extspringcache.provider;

import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import com.ideaaedi.extspringcache.annotation.ExtCacheableOop;
import com.ideaaedi.extspringcache.caffeine.ExtCaffeineCacheManager;
import com.ideaaedi.extspringcache.parser.ExtCacheChecker;
import com.ideaaedi.extspringcache.redis.ExtRedisCacheManager;
import com.ideaaedi.extspringcache.redis_caffeine.ExtRedisCaffeineCacheManager;
import com.ideaaedi.extspringcache.support.EmptyObjectProvider;
import com.ideaaedi.extspringcache.support.ExtCacheHelper;
import com.ideaaedi.extspringcache.support.SafeContainer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.cache.CacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.lang.Nullable;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import static com.ideaaedi.extspringcache.constant.ExtCacheConfigPlaceholder.REDIS_CAFFEINE_CAFFEINE_AS_FIRST_CACHE;
import static com.ideaaedi.extspringcache.constant.ExtCacheConfigPlaceholder.REDIS_CAFFEINE_RESPONSE_SPRING_CONTEXT_PLACEHOLDER;
import static com.ideaaedi.extspringcache.constant.ExtCacheConfigPlaceholder.REDIS_CAFFEINE_VALUE_BACK_FILL;

/**
 * redis-caffeine CacheManager provider, 用于管理所有的 ExtRedisCaffeineCacheManager
 *
 * @author JustryDeng
 * @since 2020/11/8 12:22:26
 */
@Slf4j
@SuppressWarnings({"rawtypes"})
public class ExtRedisCaffeineCacheManagerProvider implements CacheManagerProvider {
    
    public static final String BEAN_NAME = "extRedisCaffeineCacheManagerProvider";
    
    /**
     * true:
     *      默认对spring-context中的配置作出响应。  即:在spring-context中若存在相应配置或相关bean,那么会影响所有的Redis、Caffeine。
     *      此时,可通过在使用@Redis、@Caffeine注解时,显示的指定相关配置来覆盖 spring-context中的配置
     *
     * false:
     *      默认不对spring-context中的配置作出响应。即:不管spring-context是否存在相应配置或相关bean,都不会影响Redis、Caffeine。
     *      此时,在使用@Redis、@Caffeine注解时,显示的指定相关配置依然有效
     */
    @Value(REDIS_CAFFEINE_RESPONSE_SPRING_CONTEXT_PLACEHOLDER)
    private boolean responseSpringContext;
    
    /**
     * 是否以caffeine作为一级缓存
     *     true - caffeine作为一级缓存,redis作为二级缓存
     *     false - redis作为一级缓存,caffeine作为二级缓存
     */
    @Value(REDIS_CAFFEINE_CAFFEINE_AS_FIRST_CACHE)
    private boolean redisCaffeineCaffeineAsFirstCache;
    
    /**
     * (若一级缓存没数据,二级缓存有数据), 是否回填二级缓存的数据至一级缓存
     */
    @Value(REDIS_CAFFEINE_VALUE_BACK_FILL)
    private boolean redisCaffeineValueBackFill;
    
    @Autowired(required = false)
    private CacheProperties cacheProperties;
    
    @Autowired(required = false)
    private ClassLoader classLoader;
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @Resource(name = ExtCacheChecker.BEAN_NAME)
    private ExtCacheChecker extCacheChecker;
    
    @Autowired
    private ObjectProvider> caffeineProvider;
    
    @Autowired
    private org.springframework.beans.factory.ObjectProvider caffeineSpecProvider;
    
    @Autowired
    private ObjectProvider> cacheLoaderProvider;
    
    private final Map redisCacheManagerMap = new ConcurrentHashMap<>(8);
    
    @Override
    @Nullable
    public CacheManager provide(ExtCacheableOop oop) {
        return redisCacheManagerMap.get(oop);
    }
    
    @Override
    public void afterSingletonsInstantiated() {
        // 初始化redisCacheManagerMap
        Map tmpRedisTemplateMap = applicationContext.getBeansOfType(RedisTemplate.class);
        Set redisTemplateNameSet = tmpRedisTemplateMap.keySet();
        SafeContainer.Data4RedisCaffeine.redisTemplateNameAndOopMap().forEach((k, v) -> {
            Collection oopCollection = SafeContainer.Data4RedisCaffeine.redisTemplateNameAndOopMap().get(k);
            // 校验useTemplateName是否合法
            extCacheChecker.validRedisTemplateName(redisTemplateNameSet, k, oopCollection);
            
            RedisTemplate redisTemplate = tmpRedisTemplateMap.get(k);
            ExtRedisCacheManager extRedisCacheManager = generateExtRedisCacheManager(redisTemplate);
            Iterator iterator = oopCollection.stream().iterator();
            while (iterator.hasNext()) {
                ExtCacheableOop nextOop = iterator.next();
                ExtCaffeineCacheManager extCaffeineCacheManager = generateExtCaffeineCacheManager(nextOop);
                redisCacheManagerMap.put(
                        nextOop,
                        new ExtRedisCaffeineCacheManager(extRedisCacheManager, extCaffeineCacheManager,
                                redisCaffeineCaffeineAsFirstCache, redisCaffeineValueBackFill)
                );
            }
        });
    }
    
    
    /**
     * 生成 ExtRedisCacheManager
     */
    private ExtRedisCacheManager generateExtRedisCacheManager(RedisTemplate redisTemplate) {
        ExtRedisCacheManager extRedisCacheManager;
        if (responseSpringContext) {
            extRedisCacheManager = ExtRedisCacheManager.ExtRedisCacheManagerBuilder.builder(redisTemplate)
                    .customCacheConfig(cacheProperties, classLoader).build();
        } else {
            extRedisCacheManager = ExtRedisCacheManager.ExtRedisCacheManagerBuilder.builder(redisTemplate).build();
        }
        extRedisCacheManager.initializeCaches();
        return extRedisCacheManager;
    }
    
    /**
     * 生成 ExtCaffeineCacheManager
     */
    private ExtCaffeineCacheManager generateExtCaffeineCacheManager(ExtCacheableOop oop) {
        ExtCaffeineCacheManager.ExtCaffeineCacheManagerBuilder builder;
        if (responseSpringContext) {
            builder = ExtCaffeineCacheManager.ExtCaffeineCacheManagerBuilder
                    .builder(cacheProperties, caffeineProvider, caffeineSpecProvider, cacheLoaderProvider);
        } else {
            builder = ExtCaffeineCacheManager.ExtCaffeineCacheManagerBuilder
                    .builder(new CacheProperties(), new EmptyObjectProvider<>(), new EmptyObjectProvider<>(),
                            new EmptyObjectProvider<>());
        }
        return builder.custom(
                ExtCacheHelper.buildCaffeine(oop.getCaffeine(), applicationContext, builder)
        ).build();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy