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

com.ideaaedi.extspringcache.support.SafeContainer Maven / Gradle / Ivy

The newest version!
package com.ideaaedi.extspringcache.support;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multimap;
import com.ideaaedi.extspringcache.annotation.ExtCacheableOop;
import com.ideaaedi.extspringcache.annotation.RedisOop;
import com.ideaaedi.extspringcache.enums.ExtCacheTypeEnum;
import com.ideaaedi.extspringcache.model.ExtCacheCounter;
import com.ideaaedi.extspringcache.model.ViaMethod;
import org.apache.commons.lang3.ArrayUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.Stack;

import static com.ideaaedi.extspringcache.support.ExtCacheHelper.LOG_PREFIX;

/**
 * 一个(简易的)安全类
 *
 * @author JustryDeng
 * @since 2020/11/7 15:46:35
 */
public final class SafeContainer {
    
    private SafeContainer() {
        throw new UnsupportedOperationException("safe-class cannot allow to been overrode");
    }
    
    /** 线程method_stack */
    @SuppressWarnings("AlibabaThreadLocalShouldRemove")
    public static final ThreadLocal> THREAD_LOCAL_CACHE_COUNTER = new ThreadLocal<>();
    
    /** 标识:是否刷新当前缓存 */
    @SuppressWarnings("AlibabaThreadLocalShouldRemove")
    public static final ThreadLocal THREAD_LOCAL_REFRESH_CURR_CACHE = new ThreadLocal<>();
    
    /** ExtCacheableOop容器 */
    public static final List EXT_CACHEABLE_CONTAINER =
            Collections.synchronizedList(new ArrayList<>(64));
    
    /** ViaMethod - ExtCacheableOop> map */
    private static Map VIA_METHOD_AND_OOP_MAP = ImmutableMap.of();
    
    public static Map viaMethodAndOopMap() {
        return VIA_METHOD_AND_OOP_MAP;
    }
    
    /**
     * 将{@link SafeContainer#EXT_CACHEABLE_CONTAINER}中的元素进行初始化归档分配
     * 

* 注: 因为只有在程序启动初始化时,才会调用此方法, 所以这里选择忍受直接将synchronized加在class上 */ public synchronized static void initCommonDataAssign() { Map viaMethodAndOopMap = new HashMap<>(32); // -> 填充数据至 相关容器 EXT_CACHEABLE_CONTAINER.stream().filter(Objects::nonNull).forEach(ext -> { String[] cacheNames = ext.getCacheNames(); if (ArrayUtils.isEmpty(cacheNames)) { return; } // init VIA_METHOD_AND_OOP_MAP viaMethodAndOopMap.put(ViaMethod.getInstance(ext.getMethod()), ext); }); VIA_METHOD_AND_OOP_MAP = ImmutableMap.copyOf(viaMethodAndOopMap); } /** * redis用到的相关数据 * * @author JustryDeng * @since 2020/11/9 15:07:23 */ public final static class Data4Redis { private Data4Redis() { throw new UnsupportedOperationException("safe-class cannot allow to been overrode"); } /** cacheName - Collection map */ private static Multimap CACHE_NAME_AND_OOP_MAP = ImmutableMultimap.of(); /** redisTemplate - Collection map */ private static Multimap REDIS_TEMPLATE_NAME_AND_OOP_MAP = ImmutableMultimap.of(); /** ExtCacheableOop容器 */ public static final List EXT_REDIS_CONTAINER = Collections.synchronizedList(new ArrayList<>(64)); public static Multimap cacheNameAndOopMap() { return CACHE_NAME_AND_OOP_MAP; } public static Multimap redisTemplateNameAndOopMap() { return REDIS_TEMPLATE_NAME_AND_OOP_MAP; } /** * 从{@link SafeContainer#EXT_CACHEABLE_CONTAINER}中抽取redis专有的数据, 并归档 *

* 注: 因为只有在程序启动初始化时,才会调用此方法, 所以这里选择忍受直接将synchronized加在class上 */ public synchronized static void initRedisData() { // 从EXT_CACHEABLE_CONTAINER中分离 redis专有的ExtCacheableOop EXT_CACHEABLE_CONTAINER.stream() .filter(oop -> isSpecifiedTypeOopData(oop, ExtCacheTypeEnum.REDIS)) .forEach(EXT_REDIS_CONTAINER::add); Multimap cacheNameAndOopMap = HashMultimap.create(); Multimap redisTemplateNameAndOopMap = HashMultimap.create(); // -> 填充数据至 相关容器 EXT_REDIS_CONTAINER.stream().filter(Objects::nonNull).forEach(ext -> { String[] cacheNames = ext.getCacheNames(); if (ArrayUtils.isEmpty(cacheNames)) { return; } // init CACHE_NAME_AND_OOP_MAP for (String cacheName : cacheNames) { cacheNameAndOopMap.put(cacheName, ext); } // init REDIS_TEMPLATE_NAME_AND_OOP_MAP RedisOop redis = ext.getRedis(); if (redis != null) { redisTemplateNameAndOopMap.put(redis.getUseRedisTemplate(), ext); } }); CACHE_NAME_AND_OOP_MAP = ImmutableMultimap.copyOf(cacheNameAndOopMap); REDIS_TEMPLATE_NAME_AND_OOP_MAP = ImmutableMultimap.copyOf(redisTemplateNameAndOopMap); } } /** * caffeine用到的相关数据 * * @author JustryDeng * @since 2020/11/9 15:07:23 */ public final static class Data4Caffeine { /** ExtCacheableOop容器 */ public static final Set EXT_CAFFEINE_CONTAINER = Collections.synchronizedSet(new HashSet<>()); private Data4Caffeine() { throw new UnsupportedOperationException("safe-class cannot allow to been overrode"); } /** * 从{@link SafeContainer#EXT_CACHEABLE_CONTAINER}中抽取caffeine专有的数据 *

* 注: 因为只有在程序启动初始化时,才会调用此方法, 所以这里选择忍受直接将synchronized加在class上 */ public synchronized static void initRedisData() { EXT_CACHEABLE_CONTAINER.stream() .filter(oop -> isSpecifiedTypeOopData(oop, ExtCacheTypeEnum.CAFFEINE)) .forEach(EXT_CAFFEINE_CONTAINER::add); } } /** * redis-caffeine用到的相关数据 * * @author JustryDeng * @since 2020/11/9 15:07:23 */ public final static class Data4RedisCaffeine { private Data4RedisCaffeine() { throw new UnsupportedOperationException("safe-class cannot allow to been overrode"); } /** ExtCacheableOop容器 */ public static final List EXT_REDIS_CAFFEINE_CONTAINER = Collections.synchronizedList(new ArrayList<>(64)); /** redisTemplate - Collection map */ private static Multimap REDIS_TEMPLATE_NAME_AND_OOP_MAP = ImmutableMultimap.of(); public static Multimap redisTemplateNameAndOopMap() { return REDIS_TEMPLATE_NAME_AND_OOP_MAP; } /** * 从{@link SafeContainer#EXT_CACHEABLE_CONTAINER}中抽取redis_caffeine专有的数据, 并归档 *

* 注: 因为只有在程序启动初始化时,才会调用此方法, 所以这里选择忍受直接将synchronized加在class上 */ public synchronized static void initRedisData() { // 从EXT_CACHEABLE_CONTAINER中分离 redis专有的ExtCacheableOop EXT_CACHEABLE_CONTAINER.stream() .filter(oop -> isSpecifiedTypeOopData(oop, ExtCacheTypeEnum.REDIS_CAFFEINE)) .forEach(EXT_REDIS_CAFFEINE_CONTAINER::add); Multimap redisTemplateNameAndOopMap = HashMultimap.create(); // -> 填充数据至 相关容器 EXT_REDIS_CAFFEINE_CONTAINER.stream().filter(Objects::nonNull).forEach(ext -> { String[] cacheNames = ext.getCacheNames(); if (ArrayUtils.isEmpty(cacheNames)) { return; } // init REDIS_TEMPLATE_NAME_AND_OOP_MAP RedisOop redis = ext.getRedis(); if (redis != null) { redisTemplateNameAndOopMap.put(redis.getUseRedisTemplate(), ext); } }); REDIS_TEMPLATE_NAME_AND_OOP_MAP = ImmutableMultimap.copyOf(redisTemplateNameAndOopMap); } } /** * 判断oop是否是指定缓存类型的数据 * * @param oop * 要判断的数据对象 * @param type * 指定的类型 * * @return 是否是指定缓存类型的数据 */ private static boolean isSpecifiedTypeOopData(ExtCacheableOop oop, ExtCacheTypeEnum type) { if (oop == null) { return false; } switch (type) { case REDIS: return oop.getRedis() != null && oop.getCaffeine() == null; case CAFFEINE: return oop.getRedis() == null && oop.getCaffeine() != null; case REDIS_CAFFEINE: return oop.getRedis() != null && oop.getCaffeine() != null; default: throw new IllegalArgumentException(LOG_PREFIX + "cannot support switch for enum [" + type + "], \n\t " + "curr ExtCacheableOop is -> " + oop); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy