How to consolidate local cache in a project

preface

For spring boot integrated cache analysis, please refer to the previous article( https://blog.csdn.net/buyaoshuohua1/article/details/119843101); This time, we mainly analyze the problem of integrating local caches, such as cafe. In fact, this is not troublesome. There are many online cases. Here we talk about the problems encountered in integrating projects, because redis has been used as a cache in the project and redis dependency has been introduced.

<!-- redis to configure-->        
<dependency>            
	<groupId>org.springframework.boot</groupId>            
	<artifactId>spring-boot-starter-data-redis</artifactId>        
</dependency>

Use by injection:

    @Resource
    private RedisTemplate redisTemplate;

There is also a redis annotation cache configuration in the project. In fact, the annotation @ Cacheable is not used in the project. This is the stumbling block I encountered in integrating local cache.

@Configurable
public class RedisConfig {
    @Bean(name = "redisCacheManager")
    public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
        redisCacheManager.setUsePrefix(true);
        return redisCacheManager;
    }
}

Why is it a roadblock? The reasons are as follows:
Integrating the local cache Caffeine must introduce relevant dependencies, and then inject it with the help of the automatic cache loading of springboot;

		<dependency>
            <groupId>com.github.ben-manes.caffeine</groupId>
            <artifactId>caffeine</artifactId>
        </dependency>

After reading the code of spring boot integrated cache, you will find that the cache loading order of redis is before caffeine, and the dependency of redis is also introduced in our project. Therefore, if you use local cache, you must specify the parameter configuration - spring.cache.type.

spring.cache.type=caffeine
spring.cache.caffeine.spec=initialCapacity=100,maximumSize=500,expireAfterWrite=600s

Loading order source code: specific parameters can be found in the previous article.

static {
        Map<CacheType, Class<?>> mappings = new EnumMap(CacheType.class);
        mappings.put(CacheType.GENERIC, GenericCacheConfiguration.class);
        mappings.put(CacheType.EHCACHE, EhCacheCacheConfiguration.class);
        mappings.put(CacheType.HAZELCAST, HazelcastCacheConfiguration.class);
        mappings.put(CacheType.INFINISPAN, InfinispanCacheConfiguration.class);
        mappings.put(CacheType.JCACHE, JCacheCacheConfiguration.class);
        mappings.put(CacheType.COUCHBASE, CouchbaseCacheConfiguration.class);
        mappings.put(CacheType.REDIS, RedisCacheConfiguration.class);
        mappings.put(CacheType.CAFFEINE, CaffeineCacheConfiguration.class);
        mappings.put(CacheType.SIMPLE, SimpleCacheConfiguration.class);
        mappings.put(CacheType.NONE, NoOpCacheConfiguration.class);
        MAPPINGS = Collections.unmodifiableMap(mappings);
    }

spring.cache.type=caffeine is an important configuration. Even if redis is loaded first, because we specify that the type is caffeine, the redis cache will not be injected successfully during automatic assembly. See @ Conditional({CacheCondition.class}) for the implementation of this annotation;

I configured this place and added the parameters of cafeine, but I still use the redis cache after startup. After tossing for a while, I found the reason. It's still the problem of the project itself. We said above that there is a RedisConfig configuration class in the project to manage the redis cache configuration, although we restrict the redis cache configuration after springboot startup, The redis cache is not automatically loaded and injected, but Spring is not controlled to automatically inject beans, so the second stumbling block is that when the project is started, the redis cache manager is injected through beans (Note: this also has something to do with the start of the project. If the bean is injected earlier than the caffeine assembly, the cache will still use redis, otherwise it will be caffeine), The reason why the cache manager is not injected into caffeine depends on the source code:

@Configuration
@ConditionalOnClass({Caffeine.class, CaffeineCacheManager.class})
@ConditionalOnMissingBean({CacheManager.class})
@Conditional({CacheCondition.class})
class CaffeineCacheConfiguration {}

@ConditionalOnMissingBean({CacheManager.class}) is injected only when there is no CacheManager bean, and the analysis is completed. The solution is also very simple. Just comment out the @ Configuration on the RedisConfig class and do not load the class. If there are subsequent adjustments, they can be used again.

/**
 *  This configuration does not need to be used at present. Replace it with caffeine local cache
 */
public class RedisConfig {}

Reference article:
https://zhuanlan.zhihu.com/p/109226599
https://www.cnblogs.com/cnndevelop/p/13429660.html

Keywords: Spring

Added by dotBz on Sat, 23 Oct 2021 18:11:55 +0300