欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot增加注解緩存@Cacheable的實(shí)現(xiàn)

 更新時(shí)間:2021年12月23日 10:37:51   作者:會(huì)遲到但不會(huì)缺席  
這篇文章主要介紹了springboot增加注解緩存@Cacheable的實(shí)現(xiàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

springboot增加注解緩存@Cacheable

業(yè)務(wù)層使用

@Cacheable(value = "dictionary#1800", key = "#root.targetClass.simpleName +':'+ #root.methodName +':'+ #code")
    public Object findByCode(String code) {
        //業(yè)務(wù)
    }

配置

import org.springframework.cache.Cache;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisOperations; 
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
 
public class MyRedisCacheManager extends RedisCacheManager {  
    /**
     * 過(guò)期時(shí)間分隔符
     */
    private static final String TTLSEPARATOR = "#";
    private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap(16);
    /**
     * 過(guò)期時(shí)間, 單位為 秒
     */
    private long defaultExpiration = 0;  
    public MyRedisCacheManager(RedisOperations redisOperations) {
        super(redisOperations);
    } 
 
    @Override
    public Cache getCache(String name) { 
        long expiredTime = defaultExpiration;
        if (name.contains(TTLSEPARATOR)) {
            String[] split = name.split(TTLSEPARATOR);
            String cacheName = split[0];
            try {
                expiredTime = Double.valueOf(split[1]).longValue();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Cache cache = this.cacheMap.get(name);
            if (cache != null) {
                return cache;
            } else {
                synchronized (this.cacheMap) {
                    cache = this.cacheMap.get(name);
                    if (cache == null) {
                        cache = new RedisCache(cacheName, null, super.getRedisOperations(), expiredTime);
                        if (cache != null) {
                            cache = this.decorateCache(cache);
                            this.cacheMap.put(name, cache);
                        }
                    }
 
                    return cache;
                }
            }
        } 
        return super.getCache(name);
    }  
}
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
 
@CacheConfig
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
 
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        //設(shè)置序列化Key的實(shí)例化對(duì)象
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        //設(shè)置序列化Value的實(shí)例化對(duì)象 
        ObjectMapper mapper = new ObjectMapper();
        mapper.findAndRegisterModules();
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(mapper);
        redisTemplate.setValueSerializer(serializer);
        MyRedisCacheManager mrc = new MyRedisCacheManager(redisTemplate);
        return mrc;
    } 
}

@Cacheable注解的屬性使用

cacheNames和value

指定緩存組件的名字,通過(guò)下面代碼可以看出可以將返回結(jié)果放在哪個(gè)緩存中,可以通過(guò)數(shù)組的方式指定多個(gè)緩存

 /**
  * Alias for {@link #cacheNames}.
  */
 @AliasFor("cacheNames")
 String[] value() default {};
 /**
  * Names of the caches in which method invocation results are stored.
  * <p>Names may be used to determine the target cache (or caches), matching
  * the qualifier value or bean name of a specific bean definition.
  * @since 4.2
  * @see #value
  * @see CacheConfig#cacheNames
  */
 @AliasFor("value")
 String[] cacheNames() default {};

key

緩存數(shù)據(jù)的時(shí)候使用的key,它是用來(lái)指定對(duì)應(yīng)的緩存,模擬使用方法參數(shù)值作為key的值。也可以使用SpEL表達(dá)式的值來(lái)指定

 /**
  * Spring Expression Language (SpEL) expression for computing the key dynamically.
  * <p>Default is {@code ""}, meaning all method parameters are considered as a key,
  * unless a custom {@link #keyGenerator} has been configured.
  * <p>The SpEL expression evaluates against a dedicated context that provides the
  * following meta-data:
  * <ul>
  * <li>{@code #root.method}, {@code #root.target}, and {@code #root.caches} for
  * references to the {@link java.lang.reflect.Method method}, target object, and
  * affected cache(s) respectively.</li>
  * <li>Shortcuts for the method name ({@code #root.methodName}) and target class
  * ({@code #root.targetClass}) are also available.
  * <li>Method arguments can be accessed by index. For instance the second argument
  * can be accessed via {@code #root.args[1]}, {@code #p1} or {@code #a1}. Arguments
  * can also be accessed by name if that information is available.</li>
  * </ul>
  */
 String key() default "";
名稱 位置 描述 示例
methodName root object 被調(diào)用的方法名稱 #root.methodName
Method root object 被調(diào)用的方法 #root.method.name
Target root object 當(dāng)前被調(diào)用的目標(biāo)對(duì)象 #root.target
targetClass root object 當(dāng)前被調(diào)用的目標(biāo)對(duì)象類 #root.targetClass
args root object 被調(diào)用方法的參數(shù)列表#root.args[0]
caches root object 調(diào)用的緩存列表 #root.caches[0].name
argument name evaluation context 方法的參數(shù)名稱可以直接使用#參數(shù)名 #p0,#a0等等
result evaluation context 執(zhí)行方法后的返回值 #result

可以通過(guò)這個(gè)參數(shù)提示列表看看到這個(gè)key所支持的root object對(duì)象有哪些,通過(guò)這樣的方式可以指定對(duì)應(yīng)的key值。

在這里插入圖片描述

keyGenerator

這個(gè)是表示指定的key的生成器,當(dāng)然在之前分享中我們說(shuō)過(guò)一個(gè)簡(jiǎn)單的key的生成策略。這里我們還可以通過(guò)自定的方式來(lái)實(shí)現(xiàn)這個(gè)key的生成策略。

keyGenerator

這個(gè)是表示指定的key的生成器,當(dāng)然在之前分享中我們說(shuō)過(guò)一個(gè)簡(jiǎn)單的key的生成策略。這里我們還可以通過(guò)自定的方式來(lái)實(shí)現(xiàn)這個(gè)key的生成策略。

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
import java.util.Arrays;
@Configuration
public class MyCacheConfig {
    @Bean("myKeyGenerator")
    public KeyGenerator keyGenerator(){
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                return method.getName()+"["+ Arrays.asList(params).toString()+"]";
            }
        };
    }
}

在使用的時(shí)候可以通過(guò)一下的方式進(jìn)行配置

@Cacheable(cacheNames = {"emp"},keyGenerator = "myKeyGenerator")
cacheManager指定緩存管理器
/**
  * The bean name of the custom {@link org.springframework.cache.CacheManager} to use to
  * create a default {@link org.springframework.cache.interceptor.CacheResolver} if none
  * is set already.
  * <p>Mutually exclusive with the {@link #cacheResolver}  attribute.
  * @see org.springframework.cache.interceptor.SimpleCacheResolver
  * @see CacheConfig#cacheManager
  */
 String cacheManager() default "";
 /**
  * The bean name of the custom {@link org.springframework.cache.interceptor.CacheResolver}
  * to use.
  * @see CacheConfig#cacheResolver
  */
 String cacheResolver() default "";

condition

指定復(fù)合條件的情況下才緩存。也可以通過(guò)SpEL表達(dá)式進(jìn)行設(shè)置。這個(gè)配置規(guī)則和上面表格中的配置規(guī)則是相同的。

 /**
  * Spring Expression Language (SpEL) expression used for making the method
  * caching conditional.
  * <p>Default is {@code ""}, meaning the method result is always cached.
  * <p>The SpEL expression evaluates against a dedicated context that provides the
  * following meta-data:
  * <ul>
  * <li>{@code #root.method}, {@code #root.target}, and {@code #root.caches} for
  * references to the {@link java.lang.reflect.Method method}, target object, and
  * affected cache(s) respectively.</li>
  * <li>Shortcuts for the method name ({@code #root.methodName}) and target class
  * ({@code #root.targetClass}) are also available.
  * <li>Method arguments can be accessed by index. For instance the second argument
  * can be accessed via {@code #root.args[1]}, {@code #p1} or {@code #a1}. Arguments
  * can also be accessed by name if that information is available.</li>
  * </ul>
  */
 String condition() default "";

unless(除非)

當(dāng)這個(gè)條件為true的時(shí)候,方法的返回值就不會(huì)被緩存。

/**
  * Spring Expression Language (SpEL) expression used to veto method caching.
  * <p>Unlike {@link #condition}, this expression is evaluated after the method
  * has been called and can therefore refer to the {@code result}.
  * <p>Default is {@code ""}, meaning that caching is never vetoed.
  * <p>The SpEL expression evaluates against a dedicated context that provides the
  * following meta-data:
  * <ul>
  * <li>{@code #result} for a reference to the result of the method invocation. For
  * supported wrappers such as {@code Optional}, {@code #result} refers to the actual
  * object, not the wrapper</li>
  * <li>{@code #root.method}, {@code #root.target}, and {@code #root.caches} for
  * references to the {@link java.lang.reflect.Method method}, target object, and
  * affected cache(s) respectively.</li>
  * <li>Shortcuts for the method name ({@code #root.methodName}) and target class
  * ({@code #root.targetClass}) are also available.
  * <li>Method arguments can be accessed by index. For instance the second argument
  * can be accessed via {@code #root.args[1]}, {@code #p1} or {@code #a1}. Arguments
  * can also be accessed by name if that information is available.</li>
  * </ul>
  * @since 3.2
  */
 String unless() default "";

sync

是否異步

/**
  * Synchronize the invocation of the underlying method if several threads are
  * attempting to load a value for the same key. The synchronization leads to
  * a couple of limitations:
  * <ol>
  * <li>{@link #unless()} is not supported</li>
  * <li>Only one cache may be specified</li>
  * <li>No other cache-related operation can be combined</li>
  * </ol>
  * This is effectively a hint and the actual cache provider that you are
  * using may not support it in a synchronized fashion. Check your provider
  * documentation for more details on the actual semantics.
  * @since 4.3
  * @see org.springframework.cache.Cache#get(Object, Callable)
  */
 boolean sync() default false;

注意

在使用這個(gè)屬性的時(shí)候,當(dāng)這個(gè)屬性為true的時(shí)候,unless屬性是不能使用的。

{@link #unless()} is not supported

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Collections工具類_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Collections工具類_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Collections工具類提供了大量針對(duì)Collection/Map的操作。這篇文章主要介紹了Collections工具類_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理,需要的朋友可以參考下
    2017-04-04
  • Spring Aware標(biāo)記接口使用案例解析

    Spring Aware標(biāo)記接口使用案例解析

    這篇文章主要介紹了Spring Aware標(biāo)記接口使用案例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java實(shí)現(xiàn)局域網(wǎng)聊天小程序

    Java實(shí)現(xiàn)局域網(wǎng)聊天小程序

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)局域網(wǎng)聊天小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Java中List集合去重的幾種方式詳細(xì)解析

    Java中List集合去重的幾種方式詳細(xì)解析

    這篇文章主要介紹了Java中List集合去重的幾種方式詳細(xì)解析,在日常的業(yè)務(wù)開(kāi)發(fā)中,偶爾會(huì)遇到需要將 List 集合中的重復(fù)數(shù)據(jù)去除掉的場(chǎng)景,那么今天我們來(lái)看看幾種LIst集合去重的方式,需要的朋友可以參考下
    2023-11-11
  • java對(duì)象拷貝常見(jiàn)面試題及應(yīng)答匯總

    java對(duì)象拷貝常見(jiàn)面試題及應(yīng)答匯總

    在本篇文章里小編給大家整理的是關(guān)于java對(duì)象拷貝常見(jiàn)面試題的相關(guān)內(nèi)容,需要的朋友們可以學(xué)習(xí)下。
    2020-02-02
  • Java中Elasticsearch的核心概念詳解

    Java中Elasticsearch的核心概念詳解

    這篇文章主要介紹了Java中Elasticsearch的核心概念詳解,Elasticsearch 是一個(gè)分布式、免費(fèi)和開(kāi)放的搜索和分析引擎,適用于所有類型的數(shù)據(jù),包括文本、數(shù)字、地理空間、結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù),需要的朋友可以參考下
    2023-07-07
  • Fluent Mybatis零xml配置實(shí)現(xiàn)復(fù)雜嵌套查詢

    Fluent Mybatis零xml配置實(shí)現(xiàn)復(fù)雜嵌套查詢

    本文主要介紹了Fluent Mybatis零xml配置實(shí)現(xiàn)復(fù)雜嵌套查詢,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Java缺失區(qū)間的查找方法

    Java缺失區(qū)間的查找方法

    在 Java 的算法世界里,有許多有趣又具有挑戰(zhàn)性的問(wèn)題等待我們?nèi)ヌ剿?今天,跟著小編一起來(lái)深入研究缺失區(qū)間的查找秘籍,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2025-02-02
  • SpringBoot導(dǎo)入Druid運(yùn)行失敗問(wèn)題

    SpringBoot導(dǎo)入Druid運(yùn)行失敗問(wèn)題

    這篇文章主要介紹了SpringBoot導(dǎo)入Druid運(yùn)行失敗,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 完美解決docx4j變量替換的問(wèn)題

    完美解決docx4j變量替換的問(wèn)題

    這篇文章主要介紹了完美解決docx4j變量替換的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07

最新評(píng)論