一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第17天,点击查看活动详情。
大家好,我是程序员路飞,三年的下水道打杂前端,喜欢研究技术,正在往全栈发展
欢迎小伙伴们加我微信:DZHningmeng,一起讨论,期待与大家共同成长🥂
前言
这是Spring Boot集成Spring Security的第五章,我将会通过这个系列文章,包括完整的项目搭建、编码过程实现(认证和授权),关键点讲解,来帮助大家了解Spring Security在实际项目中的应用
今天这篇内容主要是Redis持久化缓存
往期系列
Spring Boot集成Spring Security系列一之搭建项目
Spring Boot集成Spring Security系列二之查询用户
Spring Boot集成Spring Security系列三之自定义登录
Spring Boot集成Spring Security系列四之接口鉴权
功能实现
需求
在第四章,我们的Spring Security在接口每次进来的时候,每次获取userDetail和permission,当请求量大的时候对数据库的压力是比较大,而且这两个用户的信息变化的频次是低的,所以我们可以考虑把对应的信息保存在Redis中,获取数据更快,也能减小数据库压力。
引入依赖和配置
<!--redis依赖配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
在spring节点下增加配置
redis:
host: localhost # Redis服务器地址
database: 0 # Redis数据库索引(默认为0)
port: 6379
password: # Redis服务器连接密码,默认为空
jedis:
pool:
max-active: 8 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大等待时间(使用负值表示没有限制)
max-idle: 8 # 连接池中的最大空闲连接
min-idle: 0 # 连接池中的最小空闲连接
timeout: 30000ms # 连接超时时间(毫秒)
在根节点添加自定义redis配置
# 自定义Redis key
redis:
key:
prefix:
authCode: "portal:authCode:"
expire:
authCode: 120 # 验证码超期时间
实现Redis Service
package com.example.springsecurity.service;
public interface RedisService {
/**
* 存储数据
*/
void set(String key, String value);
/**
* 获取数据
*/
String get(String key);
/**
* 设置过期时间
*/
boolean expire(String key, long expire);
/**
* 删除数据
*/
void remove(String key);
/**
* 自增操作
*/
Long increment(String key, long delta);
}
实现类
package com.example.springsecurity.service.Impl;
import com.example.springsecurity.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.concurrent.TimeUnit;
public class RedisServiceImpl implements RedisService {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public void set(String key, String value) {
stringRedisTemplate.opsForValue().set(key, value);
}
@Override
public String get(String key) {
return stringRedisTemplate.opsForValue().get(key);
}
@Override
public boolean expire(String key, long expire) {
return stringRedisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
@Override
public void remove(String key) {
stringRedisTemplate.delete(key);
}
@Override
public Long increment(String key, long delta) {
return stringRedisTemplate.opsForValue().increment(key, delta);
}
}
修改UserServiceImpl
@Override
public User queryUserByUsername(String username) {
String userStr = redisService.get(REDIS_KEY_PREFIX_AUTH_CODE + username);
User user = null;
if(userStr == null) {
user = userMapper.queryUserByName(username);
redisService.set(REDIS_KEY_PREFIX_AUTH_CODE + username, JSONUtil.toJsonStr(user));
redisService.expire(REDIS_KEY_PREFIX_AUTH_CODE + username, AUTH_CODE_EXPIRE_SECONDS);
} else {
user = JSONUtil.toBean(userStr, User.class);
}
return user;
}
验证
启动redis
启动项目,访问http://localhost:8080/user/queryUserByUsername?username=admin
第一次Redis没有对应用户信息的时候,会从数据库获取信息,从控制台打印的sql可以看出,而且Redis数据也成功保存
第二次访问http://localhost:8080/user/queryUserByUsername?username=admin
因为权限没有做Redis缓存,使用从数据库取,用户信息从Redis直接返回,这样就达到我们缓存的目的
当然有同学会问到如果用户信息更新我们如何处理,我们只要在用户更新的service里面set对应的key就可以完成更新Redis用户数据,保证数据的一致性
我们改造下下代码,将permission集成到用户信息里面,不用额外的key,具体可以参照源代码,这里就不具体讲解了
小结
到这里,我们的用户信息缓存就完成了,结合Redis实现功能需求,到这里我们的基本功能要求就符合要求了,后面会进入高级的内容,结合前端完成一个完整的用户登录,认证,权限的系统
🚴♀️ 结束语
通过项目实践,结合具体的步骤,输出相关的文章,给小伙伴一些有些的知识点,希望大家喜欢我的文章,希望认识到更多志同道合的伙伴,如果你也对技术感兴趣,可以加我好友,互相探讨,一起进步
Github: Cheering-baby
公众号: 程序员路飞
vx: DZHningmeng
最后,如果喜欢我的文章,可以给个赞👍或者关注➕都是对我最大的支持