springboot整合redis


1、SpringBoot配置類

2.SpringBoot整合redis及其注解式開發

 

SpringBoot配置類

 

注解標簽

   @Configuration

  @Configuration底層是含有@Component ,所以@Configuration 具有和 @Component 的作用。

  @Configuration可理解為用spring的時候xml里面的<beans>標簽。

  注: 

  1) 配置類必須以類的形式提供(不能是工廠方法返回的實例),允許通過生成子類在運行時增強(cglib 動態代理)。

  2) 配置類不能是 final 類(沒法動態代理)。

  3) 配置注解通常為了通過 @Bean 注解生成 Spring 容器管理的類。

  4) 配置類必須是非本地的(即不能在方法中聲明,不能是 private)。

  5) 任何嵌套配置類都必須聲明為static

  6) @Bean方法不能創建進一步的配置類(也就是返回的bean如果帶有@Configuration,也不會被特殊處理,只會作為普通的 bean)。

   @EnableCaching

  1) @EnableCaching注解是spring framework中的注解驅動的緩存管理功能。自spring版本3.1起加入了該注解。

  2) 如果你使用了這個注解,那么你就不需要在XML文件中配置cache manager了。

  3) 當你在配置類(@Configuration)上使用@EnableCaching注解時,會觸發一個post processor,這會掃描每一個spring bean,查看是否已經存在注解對應的緩存。如果找到了,就會自動創建一個代理攔截方法調用,使用緩存的bean執行處理。

 

  @Bean

  @Bean可理解為用spring的時候xml里面的<bean>標簽。

  注: 

  1) @Bean注解在返回實例的方法上,如果未通過@Bean指定bean的名稱,則默認與標注的方法名相同; 

  2) @Bean注解默認作用域為單例singleton作用域,可通過@Scope(“prototype”)設置為原型作用域;

  3) 既然@Bean的作用是注冊bean對象,那么完全可以使用@Component@Controller@Service@Repository等注解注冊bean(在需要注冊的類上加注解),當然需要配置@ComponentScan注解進行自動掃描。

 

 

 

導入redis的依賴

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>

 

 

 

配置application.yml

redis:
       database: 0
       host: 192.168.197.128
       port: 6379
       password: 123456
       jedis:
           pool:
               max-active: 100
               max-idle: 3
               max-wait: -1
               min-idle: 0
       timeout: 1000

 

 

創建RedisConfig

RedisConfig類用於Redis數據緩存。

 //繼承CachingConfigurerSupport,為了自定義生成KEY的策略。可以不繼承。

 

package com.hmc.springboot02.redis;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;
import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;


/**
 * redis配置類
 **/
@Configuration
@EnableCaching//開啟注解式緩存
//繼承CachingConfigurerSupport,為了自定義生成KEY的策略。可以不繼承。
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * 生成key的策略 根據類名+方法名+所有參數的值生成唯一的一個key
     *
     * @return
     */
    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    /**
     * 管理緩存
     *
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //通過Spring提供的RedisCacheConfiguration類,構造一個自己的redis配置類,從該配置類中可以設置一些初始化的緩存命名空間
        // 及對應的默認過期時間等屬性,再利用RedisCacheManager中的builder.build()的方式生成cacheManager:
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();  // 生成一個默認配置,通過config對象即可對緩存進行自定義配置
        config = config.entryTtl(Duration.ofMinutes(1))     // 設置緩存的默認過期時間,也是使用Duration設置
                .disableCachingNullValues();     // 不緩存空值

        // 設置一個初始化的緩存空間set集合
        Set<String> cacheNames = new HashSet<>();
        cacheNames.add("my-redis-cache1");
        cacheNames.add("my-redis-cache2");

        // 對每個緩存空間應用不同的配置
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
        configMap.put("my-redis-cache1", config);
        configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(120)));

        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)     // 使用自定義的緩存配置初始化一個cacheManager
                .initialCacheNames(cacheNames)  // 注意這兩句的調用順序,一定要先調用該方法設置初始化的緩存名,再初始化相關的配置
                .withInitialCacheConfigurations(configMap)
                .build();
        return cacheManager;
    }

    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        //使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(默認使用JDK的序列化方式)
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);

        template.setValueSerializer(serializer);
        //使用StringRedisSerializer來序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(factory);
        return stringRedisTemplate;
    }

}

 

 

 

 

詳細針對下面這段代碼進行講解

 

 /**
     * 管理緩存
     *
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        //通過Spring提供的RedisCacheConfiguration類,構造一個自己的redis配置類,從該配置類中可以設置一些初始化的緩存命名空間
        // 及對應的默認過期時間等屬性,再利用RedisCacheManager中的builder.build()的方式生成cacheManager:
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();  // 生成一個默認配置,通過config對象即可對緩存進行自定義配置
        config = config.entryTtl(Duration.ofMinutes(1))     // 設置緩存的默認過期時間,也是使用Duration設置
                .disableCachingNullValues();     // 不緩存空值

        // 設置一個初始化的緩存空間set集合
        Set<String> cacheNames = new HashSet<>();
        cacheNames.add("my-redis-cache1");
        cacheNames.add("my-redis-cache2");

        // 對每個緩存空間應用不同的配置
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
        configMap.put("my-redis-cache1", config);
        configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(120)));

        RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory)     // 使用自定義的緩存配置初始化一個cacheManager
                .initialCacheNames(cacheNames)  // 注意這兩句的調用順序,一定要先調用該方法設置初始化的緩存名,再初始化相關的配置
                .withInitialCacheConfigurations(configMap)
                .build();
        return cacheManager;
    }

 

 

 

 

在整合ehcache的時候,會有一個配置文件spring-ehcache.xml如下

 

<!-- 使用ehcache緩存 -->
    <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache.xml"/>
        <property name="shared" value="true"></property>
    </bean>
    <!-- 默認是cacheManager -->
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="cacheManagerFactory"/>
    </bean>

 

ehcache.xml

<!--defaultCache:默認的管理策略-->
    <!--eternal:設定緩存的elements是否永遠不過期。如果為true,則緩存的數據始終有效,如果為false那么還要根據timeToIdleSeconds,timeToLiveSeconds判斷-->
    <!--maxElementsInMemory:在內存中緩存的element的最大數目-->
    <!--overflowToDisk:如果內存中數據超過內存限制,是否要緩存到磁盤上-->
    <!--diskPersistent:是否在磁盤上持久化。指重啟jvm后,數據是否有效。默認為false-->
    <!--timeToIdleSeconds:對象空閑時間(單位:秒),指對象在多長時間沒有被訪問就會失效。只對eternal為false的有效。默認值0,表示一直可以訪問-->
    <!--timeToLiveSeconds:對象存活時間(單位:秒),指對象從創建到失效所需要的時間。只對eternal為false的有效。默認值0,表示一直可以訪問-->
    <!--memoryStoreEvictionPolicy:緩存的3 種清空策略-->
    <!--FIFO:first in first out (先進先出)-->
    <!--LFU:Less Frequently Used (最少使用).意思是一直以來最少被使用的。緩存的元素有一個hit 屬性,hit 值最小的將會被清出緩存-->
    <!--LRU:Least Recently Used(最近最少使用). (ehcache 默認值).緩存的元素有一個時間戳,當緩存容量滿了,而又需要騰出地方來緩存新的元素的時候,那么現有緩存元素中時間戳離當前時間最遠的元素將被清出緩存-->
    <defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"
                  timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>

 

 

所以紅色代碼的意思是:從RedisCacheConfiguration獲取一個默認的緩存策略,針對這一策略做對應的調整,生成一個全新的策略。然后,初始化兩個緩存槽,賦予名字my-redis-cache1和my-redis-cache2,,賦予再基於之前的緩存策略,初始化兩個緩存策略,存儲與configMap,然后策略與緩存槽對應上,生成緩存管理器交個spring進行管理,替代掉SSM時代的配置文件。

 

ssm框架中如果整合redis,那么會有個spring-redis.xml配置文件,里面的配置內容如下

 

<!-- 1. 引入properties配置文件 -->
    <!--<context:property-placeholder location="classpath:redis.properties" />-->

    <!-- 2. redis連接池配置-->
    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!--最大空閑數-->
        <property name="maxIdle" value="${redis.maxIdle}"/>
        <!--連接池的最大數據庫連接數  -->
        <property name="maxTotal" value="${redis.maxTotal}"/>
        <!--最大建立連接等待時間-->
        <property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
        <!--逐出連接的最小空閑時間 默認1800000毫秒(30分鍾)-->
        <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}"/>
        <!--每次逐出檢查時 逐出的最大數目 如果為負數就是 : 1/abs(n), 默認3-->
        <property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}"/>
        <!--逐出掃描的時間間隔(毫秒) 如果為負數,則不運行逐出線程, 默認-1-->
        <property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}"/>
        <!--是否在從池中取出連接前進行檢驗,如果檢驗失敗,則從池中去除連接並嘗試取出另一個-->
        <property name="testOnBorrow" value="${redis.testOnBorrow}"/>
        <!--在空閑時檢查有效性, 默認false  -->
        <property name="testWhileIdle" value="${redis.testWhileIdle}"/>
    </bean>

    <!-- 3. redis連接工廠 -->
    <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
          destroy-method="destroy">
        <property name="poolConfig" ref="poolConfig"/>
        <!--IP地址 -->
        <property name="hostName" value="${redis.hostName}"/>
        <!--端口號  -->
        <property name="port" value="${redis.port}"/>
        <!--如果Redis設置有密碼  -->
        <property name="password" value="${redis.password}"/>
        <!--客戶端超時時間單位是毫秒  -->
        <property name="timeout" value="${redis.timeout}"/>
    </bean>

    <!-- 4. redis操作模板,使用該對象可以操作redis  -->
    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
        <!--如果不配置Serializer,那么存儲的時候缺省使用String,如果用User類型存儲,那么會提示錯誤User can't cast to String!!  -->
        <property name="keySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <property name="hashKeySerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
        </property>
        <property name="hashValueSerializer">
            <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
        </property>
        <!--開啟事務  -->
        <property name="enableTransactionSupport" value="true"/>
    </bean>

    <!-- 5.使用中間類解決RedisCache.RedisTemplate的靜態注入,從而使MyBatis實現第三方緩存 -->
    <bean id="redisCacheTransfer" class="com.javaxl.ssm2.util.RedisCacheTransfer">
        <property name="redisTemplate" ref="redisTemplate"/>
    </bean>

 

 

其中前面redis鏈接工廠的創建,已經交於springboot中的application.yml文件來完成。所以,springboot整合redis我們只需要關注下面這部分配置。

 

 @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        //使用Jackson2JsonRedisSerializer來序列化和反序列化redis的value值(默認使用JDK的序列化方式)
        Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);

        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);

        template.setValueSerializer(serializer);
        //使用StringRedisSerializer來序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(factory);
        return stringRedisTemplate;
    }

}

 

 

 

 

SpringBoot整合redis及其注解式開發

常用緩存注解

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

主要參數說明: 

  1) value  

  緩存的名稱,在 spring 配置文件中定義,必須指定至少一個,

  例如:@Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”}

  2) key :緩存的 key,可以為空,

  如果指定要按照 SpEL 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合,

  例如:@Cacheable(value=”testcache”,key=”#userName”) 

  3) condition :緩存的條件,可以為空,

 

案例如下:

 

service

 

 

 實現類

 

 測試代碼 id>500

 

 

 

 

 

 

 

 

 

 id<500的時候就不會緩存

 

 

 可以看出兩次查詢都查了數據庫

 

@CachePut:作用是主要針對方法配置,能夠根據方法的請求參數對其結果進行緩存,和 @Cacheable 不同的是,它每次都會觸發真實查詢

  方法的調用 

  主要參數說明:

  參數配置和@Cacheable一樣。

 

 

 

 

 

 

 結果看出兩次都觸發了真實查詢

 

 

 

 

 

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

  

  主要參數說明:

  1value key condition 參數配置和@Cacheable一樣。

  2) allEntries

  是否清空所有緩存內容,缺省為 false

  如果指定為 true,則方法調用后將立即清空所有緩存,

  例如:@CachEvict(value=”testcache”,allEntries=true) 

 

 

 

 

 

 

 

 

這時redis里面是有數據的

 

 

 

 

 緩存數據已清空

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM