溫馨提示×

溫馨提示×

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

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

SpringBoot集成Redis并自定義對象序列化操作的示例分析

發(fā)布時間:2021-06-22 11:00:53 來源:億速云 閱讀:242 作者:小新 欄目:開發(fā)技術(shù)

這篇文章主要為大家展示了“SpringBoot集成Redis并自定義對象序列化操作的示例分析”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學習一下“SpringBoot集成Redis并自定義對象序列化操作的示例分析”這篇文章吧。

SpringBoot項目使用redis非常簡單,pom里面引入redis的場景啟動器,在啟動類上加@EnableCaching注解,項目啟動會自動匹配上redis,這樣項目中就可以愉快地使用了,

使用方法:要么使用@Cacheable一類的注解自動緩存,要么使用RedisTemplate手動緩存。

(前提是你的本機或者是遠程主機要先搭好redis環(huán)境)

雖然SpringBoot好用,但這里也有好多坑,

下面,我將詳細記錄整合步驟

1.創(chuàng)建一個SpringBoot項目

pom文件中引入cache和redis依賴

<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>

2.新建cache數(shù)據(jù)庫,創(chuàng)建員工表employee

寫好DAO,service,controller,配置文件application.yml中配好數(shù)據(jù)源和redis地址

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3305/cache
    username: root
    password: 123456
  redis:
    host: 127.0.0.1
    port: 6379
    password: hehuiredis177
    
mybatis:
  configuration:
    map-underscore-to-camel-case: true
  mapper-locations:
  - classpath:mybatis/mapper/*.xml
  
debug: true

3.SpringBoot主啟動類上加@EnableCaching注解

service類@Cacheable(cacheNames=“employee”)注解

@Service
public class EmployeeService {
 @Autowired private EmployeeDao employeeDao;
 
 @Cacheable(cacheNames="employee")
 public List<Employee> findAll(){
  System.out.println("查詢所有員工......");
  return employeeDao.findAll();
 }
 
 @Cacheable(cacheNames="employee--id")
 public Employee selectEmp(Integer id){
  System.out.println("查詢員工:"+id);
  return employeeDao.selectById(id);
 }
}

4.啟動項目(application.yml加上debug:true可以將自動配置報告打印在控制臺方便觀察)

SpringBoot集成Redis并自定義對象序列化操作的示例分析

項目啟動時,自動配置報告提示Redis已經(jīng)matched(這里說一下,你如果沒有引入redis而又在啟動類上加了@EnableCaching注解,SpringBoot會自動給你匹配一個SimpleCacheConfiguration緩存,它的底層用了一個key-value的Map,不能像redis一樣持久化,您得注意,好好權(quán)衡一下用不用,筆者不建議使用,像SQLite、H2這些一樣,玩具型的,只適合個人博客等非正式場合使用,有輕量級的優(yōu)點,也有不可靠,不好管理的缺點)

5.然后訪問 http://localhost:8080/emp/1

SpringBoot集成Redis并自定義對象序列化操作的示例分析

500錯誤,服務(wù)端有問題,仔細閱讀報錯信息,是實體類沒有序列化導(dǎo)致的,好吧,那我就實現(xiàn)Serializable接口

6.練武不練功,到老一場空,實現(xiàn)序列化Serializable就可以了嗎?

是可以了,但這只是巧合,再去訪問,確實可以

SpringBoot集成Redis并自定義對象序列化操作的示例分析

去看redis

SpringBoot集成Redis并自定義對象序列化操作的示例分析

什么東西啊,看不懂…

SpringBoot集成Redis并自定義對象序列化操作的示例分析

但第二次以后確實走了緩存,離成功又近了一步

再去試一下查所有

SpringBoot集成Redis并自定義對象序列化操作的示例分析

也可以

緩存也有

SpringBoot集成Redis并自定義對象序列化操作的示例分析

7.為什么實現(xiàn)Serializable接口就可以了,這就得開始扒源碼了,開始練功…

去看RedisTemplate這個類

SpringBoot集成Redis并自定義對象序列化操作的示例分析

對象默認實現(xiàn)序列化

怎么實現(xiàn)的呢?

接著往下看

SpringBoot集成Redis并自定義對象序列化操作的示例分析

默認用的是jdk的序列化機制

所以實現(xiàn)Serializable接口就可以,巧合?。?!

8.繼續(xù)練功

redis里這么亂,看不懂,這顯然不是我們想要的,我們要的是json,輕量易讀的json才是我們的目標,欲存json,必須改變序列化機制,把jdk的序列化替換掉

繼續(xù)讀源碼

找到RedisAutoConfiguration這個類,看它是怎么自動配置的

里面有個內(nèi)部類RedisConfiguration

SpringBoot集成Redis并自定義對象序列化操作的示例分析

初始化的時候,把RedisTemplate和StringRedisTemplate放在了IOC容器里,也就是說我們可以在我們自己的代碼里注入這兩個類,然后手動緩存

而@Cacheable注解使用的是RedisTemplate,那么分析一下RedisTemplate

		@Bean
		@ConditionalOnMissingBean(name = "redisTemplate")
		public RedisTemplate<Object, Object> redisTemplate(
				RedisConnectionFactory redisConnectionFactory)
				throws UnknownHostException {
			RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
			template.setConnectionFactory(redisConnectionFactory);
			return template;
		}
RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();

直接new了一個RedisTemplate然后把它返回,呵呵!就從這里入手

@ConditionalOnMissingBean(name = “redisTemplate”)

表示我們可以自定義RedisTemplate,我們有RedisTemplate,就用我們的,否則就用默認,我們不喜歡你的,要json就要自己配一個RedisTemplate

自己寫

package com.hehui.config;
import java.net.UnknownHostException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
/**
 * 自定義redis配置
 * @author hehui 
 * @date 2019年3月12日
 *
 */
@Configuration
public class MyRedisConfig {
	@Bean
	public RedisTemplate<Object, Object> redisTemplate(
			RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
		template.setConnectionFactory(redisConnectionFactory);
		Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
		template.setDefaultSerializer(serializer);
		return template;
	}
}
Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class);
template.setDefaultSerializer(serializer);

只多了這兩行代碼,其它什么都沒變。

為什么要用Jackson2JsonRedisSerializer呢?

因為Jackson2JsonRedisSerializer實現(xiàn)了RedisSerializer接口

SpringBoot集成Redis并自定義對象序列化操作的示例分析

9.再訪問 http://localhost:8080/emp/1

SpringBoot集成Redis并自定義對象序列化操作的示例分析

觀察redis

SpringBoot集成Redis并自定義對象序列化操作的示例分析

key是我們要的key,value是我們要的value

再刷新頁面

SpringBoot集成Redis并自定義對象序列化操作的示例分析

不會吧!?。?/p>

去緩存找,找到了,反序列化失敗…

轉(zhuǎn)換異常,看來不能用Jackson2JsonRedisSerializer,換成GenericJackson2JsonRedisSerializer

換了之后,刷新頁面

SpringBoot集成Redis并自定義對象序列化操作的示例分析

報錯信息變了,這是不能讀取json,現(xiàn)在redis里的json是Jackson2JsonRedisSerializer序列化的,

GenericJackson2JsonRedisSerializer當然不認識咯,清了redis再試

SpringBoot集成Redis并自定義對象序列化操作的示例分析

好了。

10.試試查所有 http://localhost:8080/list

SpringBoot集成Redis并自定義對象序列化操作的示例分析

報錯?。。?/p>

SimpleKey and no properties discovered 沒有key 什么情況?

于是繼續(xù)讀源碼,看key是咋生成的

	/**
	 * Generate a key based on the specified parameters.
	 */
	public static Object generateKey(Object... params) {
		if (params.length == 0) {
			return SimpleKey.EMPTY;
		}
		if (params.length == 1) {
			Object param = params[0];
			if (param != null && !param.getClass().isArray()) {
				return param;
			}
		}
		return new SimpleKey(params);
	}

是根據(jù)參數(shù)來的,我查詢所有,是沒有參數(shù)的,這樣key就為空

if (params.length == 0) {
return SimpleKey.EMPTY;
}

這怎么行,開發(fā)中,不傳參的方法多的很,這樣生成key肯定不行撒

于是重寫key的生成策略,用【類名+方法名+參數(shù)名】這樣就可以保證key不為空

package com.hehui.config;
import java.lang.reflect.Method;
import java.net.UnknownHostException;
import java.util.Arrays;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
/**
 * 自定義redis配置
 * @author hehui 
 * @date 2019年3月12日
 *
 */
@Configuration
public class MyRedisConfig extends CachingConfigurerSupport{
	@Bean
	public RedisTemplate<Object, Object> redisTemplate(
			RedisConnectionFactory redisConnectionFactory)
			throws UnknownHostException {
		RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
		template.setConnectionFactory(redisConnectionFactory);
//		Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
		GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
		template.setDefaultSerializer(serializer);
		return template;
	}
	@Bean
	@Override
	public KeyGenerator keyGenerator() {
		return new KeyGenerator() {
            public Object generate(Object target, Method method, Object... objects) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName()).append(".").append(method.getName()).append(Arrays.toString(objects));
                return sb.toString();
            }
        };
	}
}

extends CachingConfigurerSupport并重寫keyGenerator方法

測試通過

SpringBoot集成Redis并自定義對象序列化操作的示例分析

redis

SpringBoot集成Redis并自定義對象序列化操作的示例分析

json中還帶有@Class相當好。

11.好啦,相當曲折地把redis整合并自定義配置到SpringBoot中。

以上是“SpringBoot集成Redis并自定義對象序列化操作的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(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