SpringBoot2.x操作緩存的新姿勢,學到了


SpringBoot2.x操作緩存的新姿勢,學到了


一、介紹

spring cache 是spring3版本之後引入的一項技術,可以簡化對於緩存層的操作,spring cache與springcloud stream類似,都是基於抽象層,可以任意切換其實現。

其核心是CacheManager、Cache這兩個接口,所有由spring整合的cache都要實現這兩個接口、Redis的實現類則是 RedisCache 和 RedisManager。

二、使用

1、查詢

需要導入的依賴

<code><dependency>    <groupid>org.springframework.boot/<groupid>    <artifactid>spring-boot-starter-cache/<artifactid>/<dependency><dependency>    <groupid>org.springframework.boot/<groupid>    <artifactid>spring-boot-starter-data-redis/<artifactid>/<dependency>/<code>

編寫對於cache的配置

<code>@EnableCaching@SpringBootConfigurationpublic class CacheConfig {    @Autowired    private RedisConnectionFactory connectionFactory;    @Bean // 如果有多個CacheManager的話需要使用@Primary直接指定那個是默認的    public RedisCacheManager cacheManager() {        RedisSerializer<string> redisSerializer = new StringRedisSerializer();        Jackson2JsonRedisSerializer<object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);        ObjectMapper om = new ObjectMapper();        // 防止在序列化的過程中丟失對象的屬性        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);        // 開啟實體類和json的類型轉換        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);        jackson2JsonRedisSerializer.setObjectMapper(om);        // 配置序列化(解決亂碼的問題)        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()   .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))             .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))                // 不緩存空值                .disableCachingNullValues()                // 1分鐘過期                .entryTtl(Duration.ofMinutes(1))                ;        RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory)                .cacheDefaults(config)                .build();        return cacheManager;    }}/<object>/<string>/<code>

進行以上配置即可使用springboot cache了,還有一個key的生成策略的配置(可選)

<code>@Beanpublic KeyGenerator keyGenerator() {    return (target, method, params) -> {        StringBuffer key = new StringBuffer();        key.append(target.getClass().getSimpleName() + "#" + method.getName() + "(");        for (Object args : params) {            key.append(args + ",");        }        key.deleteCharAt(key.length() - 1);        key.append(")");        return key.toString();    };}/<code>

注意:如果配置了KeyGenerator ,在進行緩存的時候如果不指定key的話,最後會把生成的key緩存起來,如果同時配置了KeyGenerator 和key則優先使用key。推薦:深入SpringBoot核心註解原理

在controller或者service的類上面添加 @CacheConfig ,註解裡面的參數詳情見下表:


SpringBoot2.x操作緩存的新姿勢,學到了


在標有@CacheConfig的類裡面編寫一個查詢單個對象的方法並添加 @Cacheable註解

<code>@Cacheable(key = "#id", unless = "#result == null") @PatchMapping("/course/{id}")public Course courseInfo(@PathVariable Integer id) {    log.info("進來了 .. ");    return courseService.getCourseInfo(id);}/<code>

執行完該方法後,執行結果將會被緩存到Redis:

SpringBoot2.x操作緩存的新姿勢,學到了

@Cacheable註解中參數詳情見下表:


SpringBoot2.x操作緩存的新姿勢,學到了


2、修改

編寫一個修改的方法,參數傳對象,返回值也改成這個對象

<code>@PutMapping("/course")public Course modifyCoruse(@RequestBody Course course) {    courseService.updateCourse(course);    return course;}/<code>

在方法上面添加 @CachePut(key = "#course.id") 註解,這個註解表示將方法的返回值更新到緩存中,註解中的參數和 @Cacheable 中的一樣,這裡就略過了。擴展:SpringBoot內容聚合

3、刪除

編寫刪除方法,在方法上添加@CacheEvict 註解

<code>@CacheEvict(key = "#id")@DeleteMapping("/course/{id}")public void removeCourse(@PathVariable Integer id) {   courseService.remove(id);}/<code>

@CacheEvict 的參數信息見下表:


SpringBoot2.x操作緩存的新姿勢,學到了


三、 基於代碼的Cache的使用

因為我們有配置的CacheManager,所以可以利用RedisCacheManager對象去手動操作cache,首先將CacheManager注入進來:

<code>@Resource private CacheManager cacheManager;@PatchMapping("/course2/{id}")public Course course2(@PathVariable Integer id) {    // 獲取指定命名空間的cache    Cache cache = cacheManager.getCache("course");    // 通過key獲取對應的value    Cache.ValueWrapper wrapper = cache.get(2);    if (wrapper == null) {        // 查詢數據庫        Course course = courseService.getCourseInfo(id);        // 加入緩存        cache.put(course.getId(), course);        return course;    } else {        // 將緩存的結果返回        // 因為配置了enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);        // 所以在進行強轉的時候不會報錯        return (Course) wrapper.get();     }}/<code>

Java知音,專注於Java實用文章推送,不容錯過!

來源:cnblogs.com/maolinjava/p/12335861.html


分享到:


相關文章: