溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

SpringBoot中怎么實現(xiàn)緩存

發(fā)布時間:2021-07-08 16:53:59 來源:億速云 閱讀:289 作者:Leah 欄目:大數(shù)據(jù)

本篇文章給大家分享的是有關(guān)SpringBoot中怎么實現(xiàn)緩存,小編覺得挺實用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

簡介

Spring 定義 CacheManager 和 Cache 接口用來統(tǒng)一不同的緩存技術(shù)。例如 JCache、 EhCache、 Hazelcast、 Guava、 Redis 等。在使用 Spring 集成 Cache 的時候,我們需要注冊實現(xiàn)的 CacheManager 的 Bean。Spring Boot 默認使用的是 SimpleCacheConfiguration,即使用 ConcurrentMapCacheManager 來實現(xiàn)的緩存。

CacheManager:緩存管理器,管理各種緩存組件

CacheManager描述
SimpleCacheManager使用檢點 Collection 來存儲緩存,主要用于測試
ConcurrentMapCacheManager使用 ConcurrentMap 存儲緩存
NoOpCacheManager僅用于測試,不會實際存儲緩存
EhCacheCacheManager使用 EhCache 作為緩存技術(shù)
GuavaCacheManager使用 Guava 作為緩存技術(shù)
HazelcastCacheManager使用 Hazelcast 作為緩存技術(shù)
JCacheCacheManager支持 JCache(JSR-107)標(biāo)準(zhǔn)的實現(xiàn)作為緩存技術(shù)
RedisCacheManager使用 Redis 作為緩存技術(shù)

Cache 注解詳解

1. @CacheConfig

@CacheConfig:主要用于配置該類中會用到的一些共用的緩存配置。
在這里 @CacheConfig(cacheNames = “users”):配置了該數(shù)據(jù)訪問對象中返回的內(nèi)容將存儲于名為 users 的緩存對象中,我們也可以不使用該注解,直接通過 @Cacheable 自己配置緩存集的名字來定義。

2. @Cacheable

@Cacheable:主要針對方法配置,能夠根據(jù)方法的請求參數(shù)對其結(jié)果進行緩存。同時在查詢時,會先從緩存中獲取,若不存在才再發(fā)起對數(shù)據(jù)庫的訪問。該注解主要有下面幾個參數(shù):

  • value、cacheNames:兩個等同的參數(shù)(cacheNames 為Spring 4 新增,作為 value 的別名),用于指定緩存存儲的集合名。由于 Spring 4 中新增了 @CacheConfig,因此在 Spring 3 中原本必須有的 value 屬性,也成為非必需項了。

  • key:緩存對象存儲在 Map 集合中的 key 值,非必需,缺省按照函數(shù)的所有參數(shù)組合作為 key 值,若自己配置需使用 SpEL表 達式,比如:@Cacheable(key = “#p0”):使用函數(shù)第一個參數(shù)作為緩存的 key 值,更多關(guān)于 SpEL 表達式的詳細內(nèi)容可參考官方文檔。

  • condition:緩存對象的條件,非必需,也需使用SpEL表達式,只有滿足表達式條件的內(nèi)容才會被緩存,比如:@Cacheable(key = “#p0”, condition = “#p0.length() < 3”),表示只有當(dāng)?shù)谝粋€參數(shù)的長度小于3的時候才會被緩存,若做此配置上面的AAA用戶就不會被緩存,讀者可自行實驗嘗試。

  • unless:另外一個緩存條件參數(shù),非必需,需使用 SpEL 表達式。它不同于 condition 參數(shù)的地方在于它的判斷時機,該條件是在函數(shù)被調(diào)用之后才做判斷的,所以它可以通過對 result 進行判斷。

  • keyGenerator:用于指定 key 生成器,非必需。若需要指定一個自定義的 key 生成器,我們需要去實現(xiàn)org.springframework.cache.interceptor.KeyGenerator 接口,并使用該參數(shù)來指定。需要注意的是,該參數(shù)與 key 是互斥的。

  • cacheManager:用于指定使用哪個緩存管理器,非必需。只有當(dāng)有多個時才需要使用。

  • cacheResolver:用于指定使用那個緩存解析器,非必需。需通過
    org.springframework.cache.interceptor.CacheResolver 接口來實現(xiàn)自己的緩存解析器,并用該參數(shù)指定。

3. @CachePut

@CachePut:配置于方法上,能夠根據(jù)參數(shù)定義條件來進行緩存,它與 @Cacheable 不同的是,它不會去檢查緩存中是否存在之前執(zhí)行過的結(jié)果,而是每次都會執(zhí)行該方法,并將執(zhí)行結(jié)果以鍵值對的形式存入緩存中,所以主要用于數(shù)據(jù)新增和修改操作上。它的參數(shù)與 @Cacheable 類似,具體功能可參考上面對 @Cacheable 參數(shù)的解析。

4. @CacheEvict

@CacheEvict:配置于函數(shù)上,通常用在刪除方法上,用來從緩存中移除相應(yīng)數(shù)據(jù)。除了同 @Cacheable 一樣的參數(shù)之外,它還有下面兩個參數(shù):

  • allEntries:非必需,默認為 false。當(dāng)為 true 時,會移除所有數(shù)據(jù)。

  • beforeInvocation:非必需,默認為 false,會在調(diào)用方法之后移除數(shù)據(jù);當(dāng)為 true 時,會在調(diào)用方法之前移除數(shù)據(jù)。

搭建 Spring Boot 默認緩存

1. 開啟緩存支持

在啟動類上添加 @EnableCaching 開啟緩存支持,進行自動掃描。

@SpringBootApplication
@EnableCaching  // 開啟緩存功能
public class CacheApplication {

	public static void main(String[] args) {
		SpringApplication.run(CacheApplication.class, args);
	}
}

2. 添加 spring-boot-starter-cache 依賴

在 pom.xml 中添加 spring-boot-starter-cache 依賴。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

3. 準(zhǔn)備數(shù)據(jù)

模擬數(shù)據(jù)庫數(shù)據(jù)

/**
 * 數(shù)據(jù)工廠,模擬數(shù)據(jù)庫的數(shù)據(jù)
 *
 * @author star
 **/
public class DataFactory {

    private DataFactory() {
    }

    private static List<UserDto> userDtoList;

    static {
        // 初始化集合
        userDtoList = new ArrayList<>();

        UserDto user = null;
        for (int i = 0; i < 10; i++) {
            user = new UserDto();
            user.setName("star" + i);
            user.setAge("2" + i);
            userDtoList.add(user);
        }
    }

    public static List<UserDto> getUserDaoList() {
        return userDtoList;
    }
}

編寫緩存業(yè)務(wù)代碼

/**
 * UserRepository
 *
 * @author star
 **/
@Repository
public class UserRepository {

    /**
     * 獲取用戶信息(此處是模擬的數(shù)據(jù))
     */
    public UserDto getUser(String username) {
        UserDto user = getUserFromList(username);
        return user;
    }

    /**
     * 刪除用戶信息
     */
    public List<UserDto> deleteUser(String username) {

        List<UserDto> userDaoList = DataFactory.getUserDaoList();
        userDaoList.remove(getUserFromList(username));

        return userDaoList;
    }

    /**
     * 新增數(shù)據(jù)
     */
    public List<UserDto> save(String username) {
        // 添加到集合
        List<UserDto> userDaoList = DataFactory.getUserDaoList();
        for (UserDto userDto : userDaoList) {
            // 不能重復(fù)添加相同數(shù)據(jù)
            if (Objects.equals(userDto.getName(), username)) {
                return userDaoList;
            }
        }
        UserDto user = new UserDto();
        user.setName(username);
        user.setAge("50");
        userDaoList.add(user);

        return userDaoList;
    }

    /**
     * 從模擬的數(shù)據(jù)集合中篩選 username 的數(shù)據(jù)
     */
    private UserDto getUserFromList(String username) {

        List<UserDto> userDaoList = DataFactory.getUserDaoList();
        for (UserDto user : userDaoList) {
            if (Objects.equals(user.getName(), username)) {
                return user;
            }
        }
        return null;
    }
}
/**
 * UserService
 *
 * @author star
 **/
@Service
@CacheConfig(cacheNames = "users")// 指定緩存名稱,在本類中是全局的
public class UserService {

    @Autowired
    private UserRepository userRepository;

    /**
     * 緩存 key 是 username 的數(shù)據(jù)到緩存 users 中,
     * 如果沒有指定 key,則方法參數(shù)作為 key 保存到緩存中
     */
    @Cacheable(key = "#username")
    public UserDto getUser(String username) {
        System.out.println("從數(shù)據(jù)庫中獲取數(shù)據(jù),而不是讀取緩存");
        return userRepository.getUser(username);
    }


    /**
     * 新增或更新緩存中的數(shù)據(jù)
     */
    @CachePut(key = "#username")
    public List<UserDto> save(String username) {
        return userRepository.save(username);
    }

    /**
     * 從緩存 users 中刪除 key 是 username 的數(shù)據(jù)
     */
    @CacheEvict(key = "#username")
    public List<UserDto> deleteUser(String username) {
        System.out.println("從數(shù)據(jù)庫中刪除數(shù)據(jù),以及緩存中的數(shù)據(jù)");
        return userRepository.deleteUser(username);
    }
}
/**
 * CacheResource
 *
 * @author star
 **/
@RestController
@RequestMapping("/api")
public class CacheResource {

    @Autowired
    private UserService userService;

    @GetMapping("/users/{username}")
    public ResponseEntity<UserDto> getUser(@PathVariable String username) {
        // 獲取數(shù)據(jù)
        UserDto user = userService.getUser(username);
        return ResponseEntity.ok(user);
    }

    @PutMapping("/users/{username}")
    public ResponseEntity<List<UserDto>> save(@PathVariable String username) {
        List<UserDto> userDtoList = userService.save(username);

        return ResponseEntity.ok(userDtoList);
    }

    @DeleteMapping("/users/{username}")
    public ResponseEntity<List<UserDto>> delete(@PathVariable String username) {
        List<UserDto> userDtoList = userService.deleteUser(username);

        return ResponseEntity.ok(userDtoList);
    }
}

以上就是SpringBoot中怎么實現(xiàn)緩存,小編相信有部分知識點可能是我們?nèi)粘9ぷ鲿姷交蛴玫降?。希望你能通過這篇文章學(xué)到更多知識。更多詳情敬請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI