Spring Boot集成shiro之使用redis缓存demo

1.背景

上次发了这篇文章《Spring Boot集成Shiro快速入门Demo》后,有网友“just.blue”后台反馈集成redis有点问题,今天特地把集成过程发出来

2.为什么要使用cache

用来减轻数据库的访问压力,从而提升查询效率。

3.Shiro使用Redis做缓存

redis环境准备

参照代码工程li面redis模块里面docker,按照要求启动即可

引入pom,xml

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

redis配置

spring:
  redis:
    database: 0
    port: 6379
    host: 127.0.0.1
    password: 123456
    timeout=3000:
    jedis:
      pool:
        max-active: 8
        max-idle: 8
        max-wait: -1
        min-idle: 0

cache接口实现

创建RedisCacheManager实现CacheManager接口

package com.et.shiro.cache;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.cache.CacheManager;

public class RedisCacheManager implements CacheManager {
    @Override
    public <K, V> Cache<K, V> getCache(String cacheKey) throws CacheException {
        return new RedisCache<>(cacheKey);
    }
}

创建RedisCache实现Cache接口

package com.et.shiro.cache;

import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.util.Collection;
import java.util.Set;

public class RedisCache<K, V> implements Cache<K, V> {
    private String cacheName;

    public RedisCache() {
    }

    public RedisCache(String cacheName) {
        this.cacheName = cacheName;
    }


    private RedisTemplate getRedisTemplate() {
        RedisTemplate redisTemplate = (RedisTemplate) ApplicationContextUtil.getBean("redisTemplate");
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }

    @Override
    public V get(K k) throws CacheException {

        return (V) getRedisTemplate().opsForHash().get(this.cacheName,k.toString());

    }

    @Override
    public V put(K k, V v) throws CacheException {

        getRedisTemplate().opsForHash().put(this.cacheName,k.toString(), v);
        return null;
    }

     @Override
    public V remove(K k) throws CacheException {

        return (V) getRedisTemplate().opsForHash().delete(this.cacheName,k.toString());
    }

    @Override
    public void clear() throws CacheException {
        getRedisTemplate().opsForHash().delete(this.cacheName);
    }

    @Override
    public int size() {
        return getRedisTemplate().opsForHash().size(this.cacheName).intValue();
    }

    @Override
    public Set<K> keys() {
        return getRedisTemplate().opsForHash().keys(this.cacheName);
    }

    @Override
    public Collection<V> values() {
        return getRedisTemplate().opsForHash().values(this.cacheName);
    }
}

获取bean工具类

package com.et.shiro.cache;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public static <T> T getBean(String beanName) {
        return (T)applicationContext.getBean(beanName);
    }

    public static <T> T getBean(Class<T> className) {
        return applicationContext.getBean(className);
    }
}

由于自定义realm中认证所需要的盐值内部并没有实现序列化接口,所以我们需要自己定一个MyByteSource继承SimpleByteSource并实现Serializable接口

package com.et.shiro.config;

import org.apache.shiro.util.SimpleByteSource;

import java.io.Serializable;

public class MyByteSource extends SimpleByteSource implements Serializable {
    public MyByteSource(String string) {
        super(string);
    }
}

在自定义的Realm中需要在认证的方法中,改写salt的处理。

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
        throws AuthenticationException {
    System.out.println("MyShiroRealm.doGetAuthenticationInfo()");
    String username = (String)token.getPrincipal();
    System.out.println(token.getCredentials());
    //query user by username
    //in here ,you can cache some data for efficient
    UserInfo userInfo = userInfoService.findByUsername(username);
    System.out.println("----->>userInfo="+userInfo);
    if(userInfo == null){
        return null;
    }
    SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
            userInfo, //username
            userInfo.getPassword(), //password
            new MyByteSource(userInfo.getCredentialsSalt()),
            //ByteSource.Util.bytes(userInfo.getCredentialsSalt()),//salt=username+salt
            getName()  //realm name
    );
    return authenticationInfo;
}

注意实体类(角色类,用户类,权限类)要记得实现Serializable接口 最后在Shiro配置类中开启缓存,使用我们自己定义的RedisManager

@Bean
public MyShiroRealm myShiroRealm(){
   MyShiroRealm myShiroRealm = new MyShiroRealm();
   myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());// 设置解密规则
   // 开启全局缓存
   myShiroRealm.setCachingEnabled(true);
   // 开启认证缓存
   myShiroRealm.setAuthenticationCachingEnabled(true);
   // 设置认证缓存管理的名字
   myShiroRealm.setAuthenticationCacheName("authenticationCache");
   // 开启授权缓存管理
   myShiroRealm.setAuthorizationCachingEnabled(true);
   // 设置授权缓存管理的名字
   myShiroRealm.setAuthorizationCacheName("authorizationCache");
   // 开启Redis缓存
   myShiroRealm.setCacheManager(new RedisCacheManager());
   return myShiroRealm;
}

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • GitHub - Harries/springboot-demo: a simple springboot demo with some components for example: redis,solr,rockmq and so on.

4.测试

启动项目,访问http://127.0.0.1:8088/userInfo/userAdd,会跳转到登录页,输入admin 123456,查看redis是否缓存了

538

登录用户,第一次会从数据库中查询,并通过RedisTemplate的put方法将用户信息装入缓存,下次再刷新首页就会从redis中查询权限,授权等信息。退出时会调用RedisTemplate中的remove方法清除向对应的用户缓存。

5.引用

  • Spring Boot集成shiro之使用redis缓存demo | Harries Blog™
  • https://www.cnblogs.com/dataoblogs/p/14121884.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/651178.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

粒子爱心特效||轻松实现浪漫效果||完整代码

关注微信公众号「ClassmateJie」有完整代码以及更多惊喜等待你的发现。 简介/效果展示 你是否曾经想过&#xff0c;在特殊的日子里给你的爱人一个惊喜&#xff1f;或者在朋友的生日派对上&#xff0c;给他们展示一个充满爱意的特效&#xff1f;今天&#xff0c;我要分享一个我…

【简单介绍下容器是什么?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

【el-table 实现自定义单选】

el-table 实现自定义单选 示例图片代码 示例图片 代码 row-click"singleElection"<el-table-columnalign"center"label"选择"><template slot-scope"scope"><el-radio:key"scope.row.id"v-model"templa…

Redis篇 String

String概念和set,get扩充 一. String类型的基本介绍二. String中set,get方法扩充 一. String类型的基本介绍 redis中所有的key都是字符串类型的,但是value的类型差异很大. redis中的字符串,直接就是二进制方式存储的,可以存储整数,二进制数据 文本数据,Json,xml还有音频等. 二.…

Windows10映射网络驱动器之后不显示映射盘

目录 背景解决步骤1、按 Windows R 打开运行2、打开注册表编辑器3、 System上新建-- DWORD(32bit)4、对新建的文件重命名5、将EnableLinkedConnections的数值改为16、退出注册表编辑器&#xff0c;重启系统。 知识扩展断开连接备份注册表 背景 目前有一台NAS服务器,和一台lin…

斯洛文尼亚普利雅玛城堡:吉尼斯世界纪录认证的世界最大溶洞城堡

除了著名的波斯托伊纳溶洞&#xff08;Postojna Cave&#xff09;&#xff0c;普利雅玛城堡&#xff08;Predjama Castle&#xff09;也是波斯托伊纳洞穴公园&#xff08;Postojna Cave Park&#xff09;不容错过的景点之一。这座城堡坐落在斯洛文尼亚&#xff08;Slovenia&…

C语言动态顺序表结构的创建、初始化结构、尾插、尾删、头插、头删、指定位置插入、指定位置删除、找指定数值下标等的介绍

文章目录 前言一、 结构创建二、 初始化结构三、 打印动态顺序表四、 销毁动态顺序表五、 尾插六、尾删七、 头插八、 头删九、指定位置插入十、指定位置删除十一、找指定数值下标总结 前言 C语言动态顺序表结构的创建、初始化结构、尾插、尾删、头插、头删、指定位置插入、指…

LabVIEW波纹补偿器无线监测系统

LabVIEW波纹补偿器无线监测系统 在石油化工、冶金及电力等行业中&#xff0c;波纹补偿器作为一种重要的补偿性元件&#xff0c;其安全稳定的运行对管道输送系统的可靠性至关重要。开发了一种基于LabVIEW的波纹补偿器无线监测系统&#xff0c;通过实时监测波纹补偿器的工作状态…

微服务八股-分布式事务-注册中心-服务保护

一、分布式事务 1.CAP和BASE 三者不能同时存在。 CP&#xff1a;由于网络分片的存在&#xff0c;如果要保证强一致性就不能写&#xff0c;此时不满足可用性 AP&#xff1a;由于网络分片的存在&#xff0c;如果要保证可用性&#xff0c;能读也能写&#xff0c;就不能保证强一致…

Day37 代码随想录打卡|二叉树篇---对称二叉树

题目&#xff1a; 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 方法&#xff1a;本体可以用递归和迭代两种方法&#xff0c;但我更喜欢迭代的方式&#xff0c;因此使用迭代的方式做一下。首先我们分析一下不对称的情况。因为对称的情况很简单&#xff0c;即两…

【社会信用体系1003】 企业违规新解:社会信用环境改善的实证分析!

今天给大家分享的是来自于国内顶级期刊金融研究2023年发表论文——《社会信用环境改善降低了企业违规吗&#xff1f;——来自“中国社会信用体系建设”的证据》所用到的重要数据集&#xff0c;该文章从企业层面探讨了社会信用系统建设对企业违规行为的影响&#xff0c;更精准地…

修改 ant design tour 漫游式导航的弹窗边框样式

一 说明 应项目要求&#xff0c;调整ant design tour 弹窗边框的样式。tour 原本样式是有遮罩层&#xff0c;因此没有边框看起来也不突兀。原图如下&#xff1a; 但是UI设计是取消遮罩层&#xff0c;并设置边框样式。当 取消 了遮罩层&#xff0c;没有设置边框样式的图片如下&a…

【开源】加油站管理系统 JAVA+Vue.js+SpringBoot+MySQL

目录 一、项目介绍 论坛模块 加油站模块 汽油模块 二、项目截图 三、核心代码 一、项目介绍 Vue.jsSpringBoot前后端分离新手入门项目《加油站管理系统》&#xff0c;包括论坛模块、加油站模块、汽油模块、加油模块和部门角色菜单模块&#xff0c;项目编号T003。 【开源…

ios 原生项目迁移flutter第一天环境

由于公司已经有第一个吃螃蟹的项目组&#xff0c;我在迁移的时候想着站在巨人的肩膀上&#xff0c;但是搭配环境一定要问清楚对方flutter版本&#xff0c;路径也要安排好&#xff0c;不然就不行。 对着自己的项目照着葫芦画瓢&#xff0c;我刚开始为了配置管理图个方便随便放&…

专为汽车内容打造的智能剪辑解决方案

汽车内容创作已成为越来越多车主和汽车爱好者热衷的活动。然而&#xff0c;如何高效、便捷地将行车途中的精彩瞬间转化为高质量的视频作品&#xff0c;一直是困扰着广大用户的一大难题。美摄科技凭借其深厚的视频处理技术和智能分析能力&#xff0c;推出了专为汽车内容记录而生…

git回退到指定版本,同时提交记录也会删除

第一步&#xff1a; git reset --hard xxx (需要恢复版本的 commit id)第二步&#xff1a;branch_name就是远程分支的名称 git push origin <branch_name> --force

JMeter性能测试:命令行执行

1. 环境准备 安装JMeter http://jmeter.apache.org/ 下载最新版本的JMeter 解压下载的压缩包 配置环境变量 为了更方便地从任何目录运行JMeter&#xff0c;将JMeter的bin目录添加到系统环境变量中。 2. 创建测试计划 在执行命令行测试之前&#xff0c;需要创建一个JMete…

Java绩效考核系统源码 springboot员工绩效考核系统源码

Java绩效考核系统源码 springboot员工绩效考核系统源码-009 源码下载地址&#xff1a;https://download.csdn.net/download/xiaohua1992/89352195 项目介绍 本系统的功能分为管理员和员工两个角色 管理员的功能有&#xff1a; &#xff08;1&#xff09;个人中心管理功能&a…

【ARM 裸机】PLL 时钟配置

直接在上一节的工程上修改&#xff0c;参考 I.MX6ULL 数据手册第十八章&#xff1b; PLL2 的频率固定为 528 Mhz&#xff0c;PLL3 的频率固定为 480 Mhz&#xff0c; 首先初始化 PLL2 的 PFD0~PFD3&#xff0c;寄存器 CCM_ANALOG_PFD_528 用于设置 4 路 PFD 的时钟&#xff0c…

vscode中使用conda虚拟环境

每一次配置环境&#xff0c;真的巨烦&#xff0c;网上的资料一堆还得一个个尝试&#xff0c;遂进行整理 1.准备安装好Anaconda 附带一篇测试教程&#xff0c;安装anaconda 2.准备安装vscode 安装地址&#xff1a;Visual Studio Code 3.创建Conda环境 搜索框搜索Anaconda…