【SpringBoot】SpringBoot 整合Redis緩存(十九)

  本章介紹SpringBoot與Redis整合,對緩存不太瞭解的能夠參考【SpringBoot】SpringBoot 緩存(十八)html

  Redis安裝參考:【Redis】安裝及簡單使用java

Redis整合

  一、SpringBoot Web項目搭建,參考【SpringBoot】SpringBoot 緩存(十八)node

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6 
 7     <groupId>com.test</groupId>
 8     <artifactId>test-springboot-cache</artifactId>
 9     <version>1.0-SNAPSHOT</version>
10 
11     <parent>
12         <groupId>org.springframework.boot</groupId>
13         <artifactId>spring-boot-starter-parent</artifactId>
14         <version>2.1.8.RELEASE</version>
15     </parent>
16 
17     <properties>
18 
19         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
20         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
21         <java.version>1.8</java.version>
22     </properties>
23 
24     <dependencies>
25 
26         <dependency>
27             <groupId>org.springframework.boot</groupId>
28             <artifactId>spring-boot-starter-web</artifactId>
29         </dependency>
30 
31         <dependency>
32             <groupId>org.springframework.boot</groupId>
33             <artifactId>spring-boot-starter-data-redis</artifactId>
34         </dependency>
35 
36 
37         <dependency>
38             <groupId>org.mybatis.spring.boot</groupId>
39             <artifactId>mybatis-spring-boot-starter</artifactId>
40             <version>2.0.1</version>
41         </dependency>
42 
43 
44 
45         <!-- mysql -->
46         <dependency>
47             <groupId>mysql</groupId>
48             <artifactId>mysql-connector-java</artifactId>
49             <version>8.0.12</version>
50         </dependency>
51 
52         <dependency>
53             <groupId>org.springframework.boot</groupId>
54             <artifactId>spring-boot-starter-test</artifactId>
55             <scope>test</scope>
56         </dependency>
57 
58     </dependencies>
59 
60 
61     <!-- SpringBoot打包插件,能夠將代碼打包成一個可執行的jar包 -->
62     <build>
63         <plugins>
64             <plugin>
65                 <groupId>org.springframework.boot</groupId>
66                 <artifactId>spring-boot-maven-plugin</artifactId>
67             </plugin>
68         </plugins>
69     </build>
70 
71 </project>
pom.xml 

  二、引入SpringBoot的redis啓動器mysql

1 <dependency>
2     <groupId>org.springframework.boot</groupId>
3     <artifactId>spring-boot-starter-data-redis</artifactId>
4 </dependency>

    查看依賴,啓動器依賴了jedisweb

1 <dependency>
2     <groupId>redis.clients</groupId>
3     <artifactId>jedis</artifactId>
4     <version>${jedis}</version>
5     <optional>true</optional>
6 </dependency>

  三、application.yml配置redis鏈接地址redis

    redis單機配置spring

1 spring: 2  redis: 3  # 主機地址 4  host: 127.0.0.1 5  # 默認端口 6  port: 6379 7  # 密碼 8     password:123456

    redis集羣模式配置sql

spring:
  redis:
    database: 0 # Redis數據庫索引(默認爲0)
    #host: 192.168.1.8
    #port: 6379
    password: 123456
    timeout: 10000 # 鏈接超時時間(毫秒)
    pool:
      max-active: 8 # 鏈接池最大鏈接數(使用負值表示沒有限制)
      max-idle: 8 # 鏈接池中的最大空閒鏈接
      max-wait: -1 # 鏈接池最大阻塞等待時間(使用負值表示沒有限制)
      min-idle: 0 # 鏈接池中的最小空閒鏈接
    cluster:
      nodes:
      - 192.168.1.8:9001
      - 192.168.1.8:9002
      - 192.168.1.8:9003
View Code

    redis哨兵模式配置數據庫

spring:
  redis:
    database: 0 # Redis數據庫索引(默認爲0)
    #host: 192.168.1.8
    #port: 6379
    password: 123456
    timeout: 10000 # 鏈接超時時間(毫秒)
    pool:
      max-active: 8 # 鏈接池最大鏈接數(使用負值表示沒有限制)
      max-idle: 8 # 鏈接池中的最大空閒鏈接
      max-wait: -1 # 鏈接池最大阻塞等待時間(使用負值表示沒有限制)
      min-idle: 0 # 鏈接池中的最小空閒鏈接
    sentinel:
      master: mymaster # master名稱
      nodes:
      - 192.168.1.8:9001
      - 192.168.1.8:9002
      - 192.168.1.8:9003
View Code

  四、查看RedisAutoConfiguration類,此類事redis的自動配置來,能夠看到它自動註冊了redisTemplate和stringRedisTemplate,2個類apache

 1 @Configuration  2 @ConditionalOnClass(RedisOperations.class)  3 @EnableConfigurationProperties(RedisProperties.class)  4 @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })  5 public class RedisAutoConfiguration {  6 
 7  @Bean  8     @ConditionalOnMissingBean(name = "redisTemplate")  9     public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) 10             throws UnknownHostException { 11         RedisTemplate<Object, Object> template = new RedisTemplate<>(); 12  template.setConnectionFactory(redisConnectionFactory); 13         return template; 14  } 15 
16  @Bean 17  @ConditionalOnMissingBean 18     public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) 19             throws UnknownHostException { 20         StringRedisTemplate template = new StringRedisTemplate(); 21  template.setConnectionFactory(redisConnectionFactory); 22         return template; 23  } 24 
25 }

  五、編寫測試類,使用redisTemplate和stringRedisTemplate操做數據庫

 1 package com.test.springboot.cache;  2 
 3 import com.test.springboot.cache.bean.Employee;  4 import com.test.springboot.cache.mapper.EmployeeMapper;  5 import org.junit.Test;  6 import org.junit.runner.RunWith;  7 import org.springframework.beans.factory.annotation.Autowired;  8 import org.springframework.boot.test.context.SpringBootTest;  9 import org.springframework.data.redis.core.RedisTemplate; 10 import org.springframework.data.redis.core.StringRedisTemplate; 11 import org.springframework.test.context.junit4.SpringRunner; 12 
13 import javax.sound.midi.Soundbank; 14 
15 @RunWith(SpringRunner.class) 16 @SpringBootTest 17 public class TestApplication { 18 
19  @Autowired 20  EmployeeMapper employeeMapper; 21 
22     // 操做k-v都是字符串的
23  @Autowired 24  StringRedisTemplate stringRedisTemplate; 25 
26     // 操做k-v都是對象
27  @Autowired 28  RedisTemplate redisTemplate; 29 
30 
31  @Test 32     public void test01(){ 33         // 給redis中保存數據
34         stringRedisTemplate.opsForValue().append("msg", "hello world"); 35         System.out.println(stringRedisTemplate.opsForValue().get("msg")); 36  } 37 
38     // 測試保存對象
39  @Test 40     public void test02(){ 41 
42         Employee emp = employeeMapper.getEmpById(1); 43         redisTemplate.opsForValue().set("emp-02", emp); 44         System.out.println(redisTemplate.opsForValue().get("emp-01")); 45  } 46  
47 } 48

    注意:

      測試方法test02中,保存對象時,會對Employee對象序列化,保存到redis中,因此Employee類必須實現Serializable接口,不然會報錯,下圖爲emp對象保存在redis中的數據。

      

    將數據以json的方式保存

      a、本身將對象轉爲json(此種就時將對象轉成json字符串)

      b、redisTmplate默認規則

      分析redisTmplate默認規則:在RedisAutoConfiguration類中,RedisTemplate是經過簡單的new出來的,其中defaultSerializer默認序列化器是使用JDK自帶的,查看RedisTemplate類

 1 public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {  2 
 3  ...  4 
 5     public RedisTemplate() {}  6     
 7  @Override  8     public void afterPropertiesSet() {  9 
10         super.afterPropertiesSet(); 11 
12         boolean defaultUsed = false; 13 
14         if (defaultSerializer == null) { 15             // 使用jdk自帶的解析器
16             defaultSerializer = new JdkSerializationRedisSerializer( 17                     classLoader != null ? classLoader : this.getClass().getClassLoader()); 18  } 19 
20  ... 21 
22  } 23 
24  ... 25 }

      若是想將數據以json的方式保存在redis中,須要本身注入一個redisTemplate,且此redisTemplate使用json的序列化器。

 1 @Bean  2 public RedisTemplate<Object, Object> jsonRedisTemplate(RedisConnectionFactory redisConnectionFactory)  3         throws UnknownHostException {  4 
 5     RedisTemplate<Object, Object> template = new RedisTemplate<>();  6  template.setConnectionFactory(redisConnectionFactory);  7     // 使用json的序列化器
 8     template.setDefaultSerializer(new Jackson2JsonRedisSerializer<Object>(Object.class));  9     return template; 10 }

      測試,使用jsonRedisTemplate來操做對象

 1 @Autowired  2 RedisTemplate jsonRedisTemplate;  3 
 4 
 5 // 測試保存對象
 6 @Test  7 public void test02(){  8 
 9     Employee emp = employeeMapper.getEmpById(1); 10     // 給redis中保存對象 11     // 默認若是保存對象,使用jdk序列號機制,序列化的數據保存在redis中
12     jsonRedisTemplate.opsForValue().set("emp-02", emp); 13     System.out.println(jsonRedisTemplate.opsForValue().get("emp-02")); 14 }

      結果以下:

      

    

    使用RestTemplate操做redis

redisTemplate.opsForValue();//操做字符串
redisTemplate.opsForHash();//操做hash
redisTemplate.opsForList();//操做list
redisTemplate.opsForSet();//操做set
redisTemplate.opsForZSet();//操做有序set

SpringBoot使用Redis作緩存

  一、使用debug=true的模式啓動項目,查看日誌,發現RedisCacheConfiguration匹配上了,而默認的

    

  二、 查看RedisCacheConfiguration類,能夠看到,在容器不存在CacheManager的時候,它就會自動注入了RedisCacheManager,經過前一章(【SpringBoot】SpringBoot 緩存(十八))SpringBoot緩存的學習,知道CacheManager是用來管理緩存的Cache的。其中CacheManager也是使用的JDK自動的序列化器

@Configuration @ConditionalOnClass(RedisConnectionFactory.class) @AutoConfigureAfter(RedisAutoConfiguration.class) @ConditionalOnBean(RedisConnectionFactory.class) // 條件在不存在CacheManager Bean的時候生效
@ConditionalOnMissingBean(CacheManager.class) @Conditional(CacheCondition.class) class RedisCacheConfiguration { private final CacheProperties cacheProperties; private final CacheManagerCustomizers customizerInvoker; private final org.springframework.data.redis.cache.RedisCacheConfiguration redisCacheConfiguration; RedisCacheConfiguration(CacheProperties cacheProperties, CacheManagerCustomizers customizerInvoker, ObjectProvider<org.springframework.data.redis.cache.RedisCacheConfiguration> redisCacheConfiguration) { this.cacheProperties = cacheProperties; this.customizerInvoker = customizerInvoker; this.redisCacheConfiguration = redisCacheConfiguration.getIfAvailable(); } // 注入CacheManager
 @Bean public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) { RedisCacheManagerBuilder builder = RedisCacheManager.builder(redisConnectionFactory) .cacheDefaults(determineConfiguration(resourceLoader.getClassLoader())); List<String> cacheNames = this.cacheProperties.getCacheNames(); if (!cacheNames.isEmpty()) { builder.initialCacheNames(new LinkedHashSet<>(cacheNames)); } return this.customizerInvoker.customize(builder.build()); } private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration( ClassLoader classLoader) { if (this.redisCacheConfiguration != null) { return this.redisCacheConfiguration; } Redis redisProperties = this.cacheProperties.getRedis(); org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration .defaultCacheConfig(); config = config.serializeValuesWith( // 使用默認的JDK序列化器
                SerializationPair.fromSerializer(new JdkSerializationRedisSerializer(classLoader))); if (redisProperties.getTimeToLive() != null) { config = config.entryTtl(redisProperties.getTimeToLive()); } if (redisProperties.getKeyPrefix() != null) { config = config.prefixKeysWith(redisProperties.getKeyPrefix()); } if (!redisProperties.isCacheNullValues()) { config = config.disableCachingNullValues(); } if (!redisProperties.isUseKeyPrefix()) { config = config.disableKeyPrefix(); } return config; } }

 

  三、測試緩存,使用@Cacheable標籤,以下,調用getEmp方法,查看緩存內容

1 @Cacheable(cacheNames="emp", key = "emp#id" /*keyGenerator = "myKeyGenerator"*/) 2 public Employee getEmp(Integer id){ 3     System.out.println("===查詢" + id + "號員工"); 4     return employeeMapper.getEmpById(id); 5 }

    緩存內容以下,存儲的也是emp對象的序列化結果

    

  四、本身注入一個CacheManager的Bean,而且使用json序列化的方式

 1 /**
 2  * 緩存管理器  3  */
 4 @Bean  5 public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {  6 
 7     //初始化一個RedisCacheWriter
 8     RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);  9 
10     //設置CacheManager的值序列化方式爲json序列化
11     RedisSerializer<Object> jsonSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class); 12     RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair 13  .fromSerializer(jsonSerializer); 14     RedisCacheConfiguration defaultCacheConfig=RedisCacheConfiguration.defaultCacheConfig() 15  .serializeValuesWith(pair); 16 
17     //設置默認超過時時間是30秒
18     defaultCacheConfig.entryTtl(Duration.ofSeconds(30)); 19     //初始化RedisCacheManager
20     return new RedisCacheManager(redisCacheWriter, defaultCacheConfig); 21 
22 }

 

  五、測試緩存,使用@Cacheable標籤,以下,測試時,先將原有緩存狀況,避免影響測試,調用getEmp方法,查看緩存內容

    

相關文章
相關標籤/搜索