日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

redistemplate使用_spring-boot-starter-data-redis源码解析与使用实战

發(fā)布時(shí)間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 redistemplate使用_spring-boot-starter-data-redis源码解析与使用实战 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

我們以spring-boot-starter-data-redis-2.1.7為例,starter本身沒有包含任何代碼,只是引入了spring-data-redis的依賴,因此肯定是在spring-boot-autoconfigure中加了自動(dòng)配置:

我們就看下這幾個(gè)配置類:

其中RedisAutoConfiguration里面就配置了我們常用的RedisTemplate,RedisRepositoriesAutoConfiguration這里面是實(shí)現(xiàn)了spring-data規(guī)范的一些配置,RedisReactiveAutoConfiguration是當(dāng)需要用Reactive方式編程的時(shí)候用的,本文忽略。

RedisAutoConfiguration

@Configuration @ConditionalOnClass(RedisOperations.class) @EnableConfigurationProperties(RedisProperties.class) //內(nèi)置了對(duì)lettuce和jedis的支持 //但是默認(rèn)只添加了lettuce的依賴,因此默認(rèn)是使用的lettuce @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class }) public class RedisAutoConfiguration { @Bean @ConditionalOnMissingBean(name = "redisTemplate") public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory); return template;} @Bean @ConditionalOnMissingBean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {StringRedisTemplate template = new StringRedisTemplate();template.setConnectionFactory(redisConnectionFactory); return template;} }

這里面內(nèi)置了對(duì)lettuce和jedis的支持,因?yàn)槟J(rèn)是引入的lettuce的jar,因此默認(rèn)會(huì)使用lettuce去訪問redis,同時(shí)這里面創(chuàng)建了一個(gè)RedisTemplate和一個(gè)StringRedisTemplate,一般我們經(jīng)常會(huì)直接注入StringRedisTemplate來(lái)訪問redis。

首先看下StringRedisTemplate:

public StringRedisTemplate() {setKeySerializer(RedisSerializer.string());setValueSerializer(RedisSerializer.string());setHashKeySerializer(RedisSerializer.string());setHashValueSerializer(RedisSerializer.string()); }

從名字也可以看出來(lái),它在序列化key、value、hash key和hash value的時(shí)候都是轉(zhuǎn)化成String存入redis的,RedisSerializer#string:

static RedisSerializer<String> string() {return StringRedisSerializer.UTF_8; } public static final StringRedisSerializer UTF_8 = new StringRedisSerializer(StandardCharsets.UTF_8);

看下具體的序列化和反序列化的方法:

@Override public String deserialize(@Nullable byte[] bytes) {return (bytes == null ? null : new String(bytes, charset)); } @Override public byte[] serialize(@Nullable String string) {return (string == null ? null : string.getBytes(charset)); }

一眼就能明白,沒什么好說(shuō)的。但是很顯然,它只能處理String類型,如果是對(duì)象得需要自己手動(dòng)轉(zhuǎn)化成String才可以,一般我們會(huì)把對(duì)象轉(zhuǎn)化成json字符串存儲(chǔ)到redis里面。

我們回頭再來(lái)看下RedisTemplate,RedisTemplate#afterPropertiesSet:

@Overridepublic void afterPropertiesSet() {boolean defaultUsed = false;//判斷是否幽默ren的序列化器if (defaultSerializer == null) {//默認(rèn)是采用jdk自帶的序列化,//也就是說(shuō)必須得實(shí)現(xiàn)Serializable接口才行defaultSerializer = new JdkSerializationRedisSerializer(classLoader != null ? classLoader : this.getClass().getClassLoader());}//默認(rèn)j就是啟用的if (enableDefaultSerializer) {//key、value、hash key、hash value都使用默認(rèn)的那個(gè)序列化器 if (keySerializer == null) {keySerializer = defaultSerializer;defaultUsed = true;}if (valueSerializer == null) {valueSerializer = defaultSerializer;defaultUsed = true;}if (hashKeySerializer == null) {hashKeySerializer = defaultSerializer;defaultUsed = true;}if (hashValueSerializer == null) {hashValueSerializer = defaultSerializer;defaultUsed = true;}}。。。}

從名字也可以看出來(lái),RedisTemplate默認(rèn)是采用JDK自帶的序列化方式來(lái)做序列化器,看一下:

public JdkSerializationRedisSerializer(@Nullable ClassLoader classLoader) {this(new SerializingConverter(), new DeserializingConverter(classLoader));}public SerializingConverter() {this.serializer = new DefaultSerializer();} public class DefaultSerializer implements Serializer<Object> {@Overridepublic void serialize(Object object, OutputStream outputStream) throws IOException {if (!(object instanceof Serializable)) {throw new IllegalArgumentException(getClass().getSimpleName() + " requires a Serializable payload " +"but received an object of type [" + object.getClass().getName() + "]");}ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);objectOutputStream.writeObject(object);objectOutputStream.flush();} }

很清楚了,最終是使用ObjectOutputStream和ObjectInputStream來(lái)讀寫對(duì)象,因此對(duì)象必須得實(shí)現(xiàn)Serializable接口才可以,最終是以二進(jìn)制的格式存儲(chǔ)到redis里面,比如:

很顯然,這種序列化方式的可讀性太不友好了。

RedisRepositoriesAutoConfiguration

它實(shí)現(xiàn)了spring-data規(guī)范,其實(shí)就是把redis以數(shù)據(jù)庫(kù)dao的形式來(lái)訪問,這個(gè)東西相對(duì)就比較復(fù)雜了,但是在實(shí)際中使用的并不是很多,我們只說(shuō)一下如何使用。

首先定義一個(gè)dao,需要繼承CrudRepository:

@Repository public interface UserDao extends CrudRepository<UserEntity,Long> { }

定義一個(gè)數(shù)據(jù)庫(kù)實(shí)體:

@RedisHash("user") public class UserEntity {@Idprivate Long id;private String username;private String password; }

@RedisHash("user")會(huì)把user對(duì)象存儲(chǔ)到一個(gè)key是user:id的hash中,比如:

定義service和controller:

@Service public class UserService {@Autowiredprivate UserDao userDao;public UserEntity save(UserEntity userEntity){userDao.save(userEntity);return userEntity;}public UserEntity findById(Long id){Optional<UserEntity> optional = userDao.findById(id);return optional.isPresent()?optional.get():null;} } @RestController public class UserController {@Autowiredprivate UserService userService;private static AtomicLong id = new AtomicLong(0);@GetMapping("/add_user")public String addUser(String username, String password){long idLong = id.incrementAndGet();userService.save(new UserEntity(idLong, username, password));UserEntity entity = userService.findById(idLong);return entity.toString();} }

總結(jié)一下

- 1.spring-boot-starter-data-redis默認(rèn)是使用lettuce去訪問redis

- 2.內(nèi)置了StringRedisTemplate和RedisTemplate,應(yīng)用可以直接使用。當(dāng)存取對(duì)象的時(shí)候,StringRedisTemplate需要手動(dòng)把對(duì)象轉(zhuǎn)化成String,RedisTemplate雖然可以直接存取對(duì)象,但是需要對(duì)象實(shí)現(xiàn)Serializable接口,同時(shí)在redis庫(kù)中的可讀性比較差。

- 3.由于存在以上的缺點(diǎn),因此可以把這兩個(gè)template的優(yōu)點(diǎn)給融合到一起,既可以直接存取對(duì)象,還可以方便人類閱讀,當(dāng)然也可以存取List和基本類型,更重要的是還可以支持給key統(tǒng)一添加前綴,趕快來(lái)使用吧:github地址:https://github.com/xjs1919/redis-client。

歡迎掃碼查看更多文章:

總結(jié)

以上是生活随笔為你收集整理的redistemplate使用_spring-boot-starter-data-redis源码解析与使用实战的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。