首页 > 其他分享 >【Shiro】3.Springboot实现缓存

【Shiro】3.Springboot实现缓存

时间:2024-10-05 10:49:05浏览次数:7  
标签:缓存 return Springboot RedisTemplate cacheName Shiro public redisTemplate

最近已经快速入门了Shiro。对于登录、授权、认证等方法,每次都是从数据库直接查询。如果登录的人员过多,对数据库来说,是一项压力。如何减轻数据库的压力。

  • EhCache 实现缓存
  • 集成 Redis 实现 Shiro 缓存(推荐使用)

在此之前,我们已经简单学会EhCacheReids的使用。

EhCache 实现缓存

Shiro 提供了缓存管理器,这样在用户第一次认证授权后访问其受限资源的时候就不用每次查询数据库从而达到减轻数据压力的作用,使用 Shiro 的缓存管理器也很简单。第一步,在pom.xml引入依赖

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>1.13.10</version>
</dependency>

ShiroConfiguratin 添加缓存配置:

 1 /**
 2  * 3.创建自定义realm
 3  * @return
 4  */
 5 @Bean
 6 public Realm getRealm(){
 7     UserRealm userRealm = new UserRealm();
 8     // 设置缓存管理器
 9     userRealm.setCacheManager(new EhCacheManager());
10     // 开启全局缓存
11     userRealm.setCachingEnabled(true);
12     // 开启认证缓存并指定缓存名称
13     userRealm.setAuthenticationCachingEnabled(true);
14     userRealm.setAuthenticationCacheName("authenicationCache");
15     // 开启缓存授权并指定缓存名称
16     userRealm.setAuthorizationCachingEnabled(true);
17     userRealm.setAuthorizationCacheName("authenicationCache");
18     return userRealm;
19 }

这样就将 EhCache 集成进来了,但是 shiro 的这个缓存是本地缓存,也就是说当程序宕机重启后仍然需要从数据库加载数据,不能实现分布式缓存的功能。

集成 Redis 实现 Shiro 缓存(推荐使用)

已知Redis的使用,我们实现了Redis的引用和配置。

在pom.xml文件引入Redis依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.5.15</version>
</dependency>

配置RedisConfig

 1 @Configuration
 2 @EnableCaching
 3 public class RedisConfig extends CachingConfigurerSupport {
 4 
 5     /**
 6      * RedisTemplate相关配置
 7      * 使redis支持插入对象
 8      *
 9      * @param factory
10      * @return 方法缓存 Methods the cache
11      */
12     @Bean
13     public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
14         RedisTemplate<String, Object> template = new RedisTemplate<>();
15         // 配置连接工厂
16         template.setConnectionFactory(factory);
17         // 序列化 key 和hashKey采用String序列化;value和hashValue采用JSON序列化
18         GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
19         template.setKeySerializer(RedisSerializer.string());
20         template.setHashKeySerializer(RedisSerializer.string());
21         // value和hashvalue采用JSON序列化
22         template.setValueSerializer(jsonRedisSerializer);
23         template.setHashValueSerializer(jsonRedisSerializer);
24         return template;
25     }
26 }

配置redis的数据库连接,这里以application.yml为例

spring:
  redis:
    database: 0     # 数据库索引,默认为0
    host: 127.0.0.1 # redis地址
    port: 6379      # redis服务器端口地址 
    # sping.redis.password 表示密码,因为密码为空,这里不设置
    jedis:
      pool:
        max-wait: 3000  # 连接池最大阻塞等待时间,单位毫秒(使用负值表示没有限制)
        min-idle: 0     # 连接池最小空闲时间
    timeout: 3000       # 连接超时时间(毫秒)

添加自定义缓存配置。自定义配置缓存管理器(RedisCacheManage)和自定义缓存方法(RedisCache)。

 1 @Autowired
 2 private RedisTemplate redisTemplate;
 3 
 4 /**
 5  * 3.创建自定义realm
 6  * @return
 7  */
 8 @Bean
 9 public Realm getRealm(){
10     SysUserRealm sysUserRealm = new SysUserRealm();
11     // 设置缓存管理器
12     sysUserRealm.setCacheManager(new RedisCacheManage(redisTemplate)); // 自定义Redis数据库缓存方法
13     // 开启全局缓存
14     sysUserRealm.setCachingEnabled(true);
15     // 开启认证缓存并指定缓存名称
16     sysUserRealm.setAuthenticationCachingEnabled(true);
17     sysUserRealm.setAuthenticationCacheName("authenicationCache");
18     // 开启缓存授权并指定缓存名称
19     sysUserRealm.setAuthorizationCachingEnabled(true);
20     sysUserRealm.setAuthorizationCacheName("authenicationCache");
21     return sysUserRealm;
22 }
 1 public class RedisCacheManage implements CacheManager {
 2     private RedisTemplate redisTemplate;
 3 
 4     public RedisCacheManage(RedisTemplate redisTemplate) {
 5          this.redisTemplate = redisTemplate;
 6     }
 7 
 8     @Override
 9     public <K, V> Cache<K, V> getCache(String s) throws CacheException {
10         return new RedisCache(s , this.redisTemplate);
11     }
12 }
 1 public class RedisCache<K,V> implements Cache<K,V> {
 2     /** 缓存名称 **/
 3     private String cacheName;
 4     private RedisTemplate redisTemplate;
 5     public RedisCache(String cacheName, RedisTemplate redisTemplate){
 6         this.cacheName = cacheName;
 7         this.redisTemplate = redisTemplate;
 8     }
 9 
10     /**
11      * 获取缓存
12      * @param k
13      * @return
14      * @throws CacheException
15      */
16     @Override
17     public V get(K k) throws CacheException {
18         System.out.println("cacheName=" +this.cacheName);
19         System.out.println("k=" + k.toString());
20         System.out.println("res=" + this.redisTemplate);
21         return (V) redisTemplate.opsForHash().get(this.cacheName,k.toString());
22     }
23 
24     /**
25      * 设置缓存Key
26      * @param k
27      * @param v
28      * @return
29      * @throws CacheException
30      */
31     @Override
32     public V put(K k, V v) throws CacheException {
33          redisTemplate.opsForHash().put(this.cacheName,k.toString(),v);
34          return null;
35     }
36 
37     /**
38      * 移除缓存Key
39      * @param k
40      * @return
41      * @throws CacheException
42      */
43     @Override
44     public V remove(K k) throws CacheException {
45         return (V)redisTemplate.opsForHash().delete(this.cacheName,k.toString());
46     }
47 
48     /**
49      * 清除缓存
50      * @throws CacheException
51      */
52     @Override
53     public void clear() throws CacheException {
54         redisTemplate.delete(this.cacheName);
55     }
56 
57     /**
58      * 获取缓存的数量
59      * @return
60      */
61     @Override
62     public int size() {
63         return redisTemplate.opsForHash().size(this.cacheName).intValue();
64     }
65 
66     @Override
67     public Set<K> keys() {
68         return (Set<K>) redisTemplate.opsForHash().values(this.cacheName);
69     }
70 
71     @Override
72     public Collection<V> values() {
73         return redisTemplate.opsForHash().values(this.cacheName);
74     }
75 }

 此时,我们可以运行测试方法(这里使用了测试接口)

 /**
     * 系统认证、授权测试
     * @return
     */
    @GetMapping("/test")
    public String test(){
        System.out.println("系统认证测试");
        String username = "christy";
        String password = Md5Utils.Md5PassWord("123456");
        System.out.println(password);
        try {
            Subject subject = SecurityUtils.getSubject();
            subject.login(new UsernamePasswordToken(username,password));
        }catch (UnknownAccountException e){
            System.err.println("认证失败:用户不存在");
            return  "redirect:/login";
        }catch (IncorrectCredentialsException e){
            System.err.println("认证失败:密码不正确");
            return  "redirect:/login";
        }catch (Exception e){
            System.err.println("认证失败");
            e.printStackTrace();
            // 如果认证失败仍然回到登录页面
            return  "redirect:/login";
        }
        return  "redirect:/login";
    }

调用接口后,我们发现Redis数据库存储了登录和授权的hash值。

 

标签:缓存,return,Springboot,RedisTemplate,cacheName,Shiro,public,redisTemplate
From: https://www.cnblogs.com/luyj00436/p/18446712

相关文章

  • 【Java】使用Ehcache缓存。
    EhCache是一个纯Java的进程内缓存框架,具有快速、精干等特点。当我们需要频繁使用某些数据时,我们可以将这些数据放到缓存中,下次取数据的时候,直接从缓存中取,这样可以节省不少时间。如果我们自己手动进行缓存的管理将是比较棘手的的,因为这已经涉及到很多底层的技术了,但是Ehcache为我......
  • 【SpringBoot】结合Redis实现缓存
    Redis经常用于缓存。接下来,我们以Springboot框架为例。实现一些Redis的基础操作,创建完SpingBoot项目后,具体步骤如下图:  pom中添加项目依赖<!--Redis缓存--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-re......
  • 古典舞在线交流:SpringBoot平台实现与优化
    第一章绪论1.1研究背景在当今的社会,可以说是信息技术的发展时代,在社会的方方面面无不涉及到各种信息的处理。信息是人们对客观世界的具体描述,是人们进行交流与联系的重要途径。人类社会就处在一个对信息进行有效合理的加工中。它将促进整个社会的发展。随着社会信息技术......
  • SpringBoot中,如何把自定义的yml配置文件中的内容和对应类的bean对象取出
    首先yml文件中的自定义配置如下login-type-config:types:k1:"yuheng0"k2:"yuheng1"我们有两个对应的类,yuheng0和yuheng1,他们都实现了say接口,并且重写了say方法。下面要通过请求k1k2获取yuheng0和yuheng1类的bean对象。注意,要记得加上Component注解......
  • springboot+vue专家库管理系统的设计与实现【开题+程序+论文】
    系统程序文件列表开题报告内容研究背景在当今知识密集型社会中,各领域专家资源成为推动科技进步、解决复杂问题的关键力量。随着信息化技术的飞速发展,如何高效管理、合理配置并利用专家资源,成为各行各业面临的重要课题。传统的人工管理方式已难以满足大规模、高效率的专家资......
  • springboot+vue作业管理系统【开题+程序+论文】
    系统程序文件列表开题报告内容研究背景随着教育信息化的快速发展,传统的教学管理模式逐渐暴露出效率低下、信息孤岛等问题。作业管理作为教学环节中的重要一环,其繁琐性和重复性使得教师和学生常常陷入沉重的负担之中。传统的纸质作业提交、批改和反馈流程不仅耗时耗力,还难以......
  • SpringBoot项目使用yml文件链接数据库异常
    SpringBoot使用properties连接数据库时没有出现问题SpringBoot使用yml连接数据库时出现:UnabletoconnecttoRedis并在报错信息中出现:发现是用户或者密码出现问题通过查询知道yml是区分数据类型的,所以如果用户名或者密码是数字的话,就要注意将密码用双引号括起来,将其识别为......
  • 美容院管理智能化:SpringBoot系统开发实战
    第四章系统设计设计一个系统不单单是设计系统的页面,可以说系统设计其本质是一个结合了众多设计过程的比较复杂的系统工程。一般来说,在完成系统设计时,需要了解和掌握很多设计的知识,有界面布局技术的知识,页面采用的字体和颜色的运用,还有页面空白的规范使用等,如何将这些元素......
  • SpringBoot美容院管理系统:开发者指南
    第三章系统分析提前通过各种渠道,比如图书馆,电脑上的网站等渠道获取跟本系统有关联的资料,同时设计调查问卷,让系统的使用者参与调查,了解其对系统的需求,然后进行系统的分析,确定本系统的开发可行性,确定本系统的功能等内容。3.1可行性分析这部分内容主要从开发的角度和运行使......
  • 【开题报告】基于Springboot+vue农村住宅房屋信息管理应用系统(程序+源码+论文) 计算机
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着农村经济的快速发展和城乡一体化进程的加速推进,农村住宅房屋作为农村居民生活与生产的重要载体,其管理效率与信息化水平日益成为影响农村现代化建......