日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Spring @Cacheable緩存注解

作者:浪子塵晨 更新時間: 2023-12-25 編程語言

一、簡介

緩存介紹

緩存,在我們的日常開發中用的非常多,是我們應對各種性能問題支持高并發的一大利器。

  • Spring 從?3.1?開始就引入了緩存的支持。定義了如下兩個接口來統一支持不同的緩存技術。

    • org.springframework.cache.Cache
    • org.springframework.cache.CacheManager
  • 我們熟知的緩存有:堆緩存(Ehcache3.xGuava CacheCaffeine等)、堆外緩存(Ehcache3.xMapDB等)、分布式緩存(RedisMemcached等)等等。

  • 常用的緩存注解:@EnableCaching@Cacheable@CachePut@CacheEvict

Cache 和 CacheManager 接口說明

  • Cache 接口包含緩存的各種操作集合,你操作緩存就是通過這個接口來操作的。
  • Cache 接口下 Spring 提供了各種 xxxCache 的實現,比如:RedisCache、EhCache、ConcurrentMapCache等。
  • CacheManager 定義了創建、配置、獲取、管理和控制多個唯一命名的 Cache。這些 Cache 存在于 CacheManager 的上下文中。

二、緩存實戰

1.開啟緩存

在 SpringBoot 的啟動類上添加注解@EnableCaching

2.@Cacheable

@Cacheable?的作用 主要針對方法配置,能夠根據方法的請求參數對其結果進行緩存。

常用屬性:

  • cacheNamesvalue:用來指定緩存組件名稱。

    @Cacheable(cacheNames = "users", key="#id")
    public User getUser(Integer id) {}
    
  • key:緩存數據的 key,可以用它來指定。默認使用所有參數的值進行組合。(key可以使用 spEL 表達式來編寫)。

    @Cacheable(cacheNames = "usersBySpEL", key="#root.methodName + '[' + #id + ']'")
    public User getUserBySpEL(Integer id) {}
    
  • keyGenerator:key 的生成器。key 和 keyGenerator 二選一使用。

    @Cacheable(cacheNames = "userByKeyGenerator", keyGenerator = "myKeyGenerator")
    public User getUserByKeyGenerator(Integer id) {}
    
  • condition:指定符合條件的情況下才緩存。

    @Cacheable(cacheNames = "userByCondition", condition = "#id > 1")
    public User getUserByCondition(Integer id) {}
    
  • unless:指定不符合條件的情況下才緩存。(可以獲取到結果進行判斷,通過 #result 獲取方法結果,unless,漢語意思,除非,指會緩存,除了。。。之外)。

    @Cacheable(cacheNames = "userByUnless", unless = "#id > 1")
    public User getUserByUnless(Integer id) {}
    
  • sync:是否使用異步模式。

3.@CachePut

@CachePut?的作用 主要針對配置,能夠根據方法的請求參數對其結果進行緩存。

  • 區別于?@Cacheable,它每次都會觸發真實方法的調用,可以保證緩存的一致性。
  • 屬性與?@Cacheable?類同。
@CachePut(cacheNames = "users" , key = "#user.id")
public User addUser(User user) {}
4.@CacheEvict

@CacheEvict?的作用 主要針對方法配置,能夠根據一定的條件對緩存進行清空

常用屬性

  • cacheNamesvalue:用來指定緩存組件名稱。
  • key:緩存數據的 key,可以用它來指定。默認使用所有參數的值進行組合。(key可以使用 spEL 表達式來編寫)。
  • condition:指定符合條件的情況下的緩存。
  • allEntries:是否清空所有緩存,缺省為false。
  • beforeInvocation:是否在方法執行前就清空,缺省為false,缺省情況下,如果方法執行拋異常,則不會清空緩存。
@CacheEvict(cacheNames = "users", key = "#id")
public void delUserCache(Integer id) {}
5.@CacheConfig

@CacheConfig?的作用 主要針對類配置,能夠設置當前類中 @Cacheable 的 value 屬性默認值。當然如果?@Cacheable?設置了 value,還是以設置的值為準。

常用屬性

  • cacheNames: 指定緩存名稱默認值。
6.@Caching

@Caching?的作用 主要針對方法配置,能夠組合多個Cache注解。比如用戶新增成功后,我們可能需要添加 id -> user、username -> user、email -> user 的緩存,此時就需要?@Caching?組合多個注解標簽了。

常用屬性

  • cacheable:組合多個?@Cacheable?注解
  • put:組合多個?@CachePut?注解
  • evict:組合多個?@CacheEvict?注解
@CacheConfig(cacheNames = "users")
public class CacheTestServiceImpl implements CacheTestService {
    /**
     * @Cacheable 的 cacheNames 默認為 "users"
     */
    @Cacheable(key="#id")
    public User getUser(Integer id) {...}
}
7.自定義緩存過期時間

7.1 設置全局默認緩存過期時間:

    // 提供默認的cacheManager,應用于全局,實現存活2天
    @Bean
    @Primary
    public CacheManager defaultCacheManager(
            RedisTemplate<?, ?> redisTemplate) {
        RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(redisTemplate.getConnectionFactory());
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofDays(2));
        return new RedisCacheManager(writer, config);
    }

7.2 定制部分緩存過期時間

  • 定制緩存過期時間,需要自定義RedisCacheManager來實現ttl設置。
  • 注意:項目中如已配置了RedisCacheManager需要在原配置的bean上添加注解?@Primary,以免造成干擾
	/**
		自定義RedisCacheManager,用于在使用@Cacheable時設置ttl
	 */
	@Bean
	public RedisCacheManager selfCacheManager(RedisTemplate<String, Object> redisTemplate) {
		RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());
		RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
				.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
		return new SelfRedisCacheManager(redisCacheWriter, redisCacheConfiguration);
	}

SelfRedisCacheManager.java

public class SelfRedisCacheManager extends RedisCacheManager {
    public SelfRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
        super(cacheWriter, defaultCacheConfiguration);
    }

    @Override
    protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {
        String[] cells = StringUtils.delimitedListToStringArray(name, "=");
        name = cells[0];
        if (cells.length > 1) {
            long ttl = Long.parseLong(cells[1]);
            // 根據傳參設置緩存失效時間,默認單位是秒
            cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(ttl));
        }
        return super.createRedisCache(name, cacheConfig);
    }
}

使用:

// value、cacheNames是等效的,ttl=600s,unless是不緩存的結果(為null時不緩存)
@Cacheable(value = "p_user=600",key = "#menu+'_'+#type+'_'+#userId",cacheManager = "selfCacheManager", unless = "#result == null")
public User getUser(...){
    xxx
}

// 當前方法執行時對應的key失效,也可以用@CachePut在當前方法執行時更新key
@CacheEvict(cacheNames = "p_user",key = "#p.menu+'_'+#p.type+'_'+#p.user")
public boolean setUser(User p){
    xxx
}


三、spEL表達式

spEL表達式

參考地址:
1.@Cacheable設置過期時間:https://blog.csdn.net/weixin_41860719/article/details/125226096

原文鏈接:https://blog.csdn.net/fygkchina/article/details/134726030

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新