Shiro-Redis-Cache - 将查询权限存入Redis

Shiro-Redis-Cache:

 

Cache:负责完成缓存数据的功能

CacheManager:负责管理Cache核心流程,重点是会创建Cache对象.

一、定义Cache组件

package com.vince.cache;

import lombok.Getter;
import lombok.Setter;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.data.redis.core.RedisTemplate;

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

@Setter
@Getter
public class MyShiroCache implements Cache {

    private String name;  // 权限缓存的标识
    private RedisTemplate<String,Object> template;

    public MyShiroCache(){}

    public MyShiroCache(String name){   // 需 get/set

        this.name=name;   // 在 cacheManager 中会调用此方法
    }

    // cache  主业务

    @Override
    public Object get(Object o) throws CacheException {
        System.out.println("检查缓存权限~");
        Object data = template.opsForValue().get(o.toString());
        if (data!=null){
            System.out.println("权限信息检查 ----命中缓存~");
            return data;
        }else{
            System.out.println("权限信息检查 ----缓存中不存在~");
            return null;
        }

    }

    @Override
    public Object put(Object o, Object o2) throws CacheException {
           template.opsForValue().set(o.toString(), o2);
        return null;
    }

   //  可以移除某个用户的权限信息的缓存,用于 subject.logout();
   //   o =key=用户凭证 ~= 用户名
    @Override
    public Object remove(Object o) throws CacheException {
        System.out.println(o+"的权限信息被清除");
        template.delete(o.toString());
        return null;
    }

    @Override
    public void clear() throws CacheException {

    }

    @Override
    public int size() {
        return 0;
    }

    @Override
    public Set keys() {
        return null;
    }

    @Override
    public Collection values() {
        return null;
    }
}

二、定义CacheManager


import lombok.Setter;
import org.apache.shiro.cache.AbstractCacheManager;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.data.redis.core.RedisTemplate;

@Setter
public class MyCacheManager  extends AbstractCacheManager {

    private RedisTemplate<String,Object> template;  // 需要注入RedisTemplate


    @Override
    protected Cache createCache(String s) throws CacheException {
        System.out.println("标识是:--"+s);
        MyShiroCache cache = new MyShiroCache(s);
        cache.setTemplate(template);
        return cache;
  

三、配置Cache和CacheManager

shiro-spring.xml:j将此文件导入spring工厂

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop.xsd
                           http://www.springframework.org/schema/tx
                           http://www.springframework.org/schema/tx/spring-tx.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">



    <!-- 整合mybaits,事务控制等 配置不变 -->
  
    <!-- 声明realm -->
    <bean id="myRealm" class="com.vince.realm.MyRealm">
        <property name="userService" ref="userServiceImpl"/>
        <property name="roleService" ref="roleServiceImpl"/>
        <property name="permissionService" ref="permissionServiceImpl"/>
         <!--密码比对器-->
        <property name="credentialsMatcher">
        <bean class="org.apache.shiro.authc.credential.HashedCredentialsMatcher">
        <property name="hashAlgorithmName" value="SHA-256"/>
        <!-- true means hex encoded, false means base64 encoded -->
        <property name="storedCredentialsHexEncoded" value="false"/>
        <property name="hashIterations" value="10000"/>
        </bean>
        </property>
    </bean>

   
 <!-- 声明CacheManager,注意Cache不用声明,会由CacheManager创建 -->
    <bean class="com.vince.cache.MyCacheManager" id="cacheManager9">
        <property name="template" ref="redisTemplate02"/>
    </bean>



    <!-- 声明SecurityManager -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="myRealm"/>
        <!--缓存管理器-->
        <property name="cacheManager" ref="cacheManager9"></property> 
    </bean>




    <!-- 生产SpringShiroFilter
         ( 持有shiro的过滤相关规则,可进行请求的过滤校验,校验请求是否合法 )
    -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager"/>
        <!--<property name="loginUrl" value="/user/login/page"/>-->
        <!--<property name="unauthorizedUrl" value="/user/error"/>-->
        <property name="filterChainDefinitions">
            <value>
               
                /user/logout = logout
            </value>
        </property>
    </bean>

    <!--引入redis文件-->
    <import resource="classpath:application-redis.xml"></import>

</beans>

redis配置文件:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!-- 连接池配置 -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最多空闲连接数 -->
        <property name="maxIdle" value="1" />
        <!-- 最多有多少连接 -->
        <property name="maxTotal" value="5" />
        <property name="minIdle" value="1"></property>
        <!-- 连接数用完时,是否阻塞,阻塞超过maxWaitMillis会抛出异常 -->
        <property name="blockWhenExhausted" value="true" />
        <!-- 检出连接时,最大等待时长 -->
        <property name="maxWaitMillis" value="30000" />
        <!-- 在检出时是否检测 -->
        <property name="testOnBorrow" value="false" />
        <!-- 空闲时是否检测连接是否可用 -->
        <property name="testWhileIdle" value="false"></property>
        <!-- Evict=驱逐  连接至少要空闲多少时间才会成为可以被驱逐线程扫描并移除 -->
        <property name="minEvictableIdleTimeMillis" value="60000"></property>
        <!-- 驱逐线程 两次驱逐之间要sleep的时间 如果小于0,则不会有驱逐线程,则minEvictableIdleTimeMillis无效-->
        <property name="timeBetweenEvictionRunsMillis" value="30000"></property>
        <!-- 驱逐线程每次最多扫描几个连接 -->
        <property name="numTestsPerEvictionRun" value="3"></property>
        <!-- last in first out 检出策略 后入先出  或 先入先出 -->
        <property name="lifo" value="true"></property>
    </bean>


    <!-- 为 redisClusterConfiguration定制参数配置-->
    <bean id="propertyPropertySource" class="org.springframework.core.env.PropertiesPropertySource">
        <constructor-arg index="0" type="java.lang.String" value="redisParam04"></constructor-arg>
        <constructor-arg index="1" type="java.util.Properties">
            <props>
                <!-- 集群中的所有或部分节点ip:port -->
                <prop key="spring.redis.cluster.nodes">192.168.11.128:9001,192.168.11.128:9005,192.168.11.128:9006</prop>
                <!--
                        默认为5,连接不到集群时,重试次数
                      -->
                <prop key="spring.redis.cluster.max-redirects">5</prop>
            </props>
        </constructor-arg>
    </bean>
<!--将 propertyPropertySource 注入-->
    <bean id="redisClusterConfiguration" class="org.springframework.data.redis.connection.RedisClusterConfiguration">
        <constructor-arg name="propertySource" ref="propertyPropertySource"/>
    </bean>



    <!-- 连接Factory -->
    <bean id="jedisConnectionFactory"
          class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
        <!-- Redis主机 -->
        <!--<property name="hostName" value="192.168.11.128"></property>-->
        <!--<property name="port" value="8000"></property>-->

        <!--redis集群-->
        <constructor-arg name="clusterConfig" ref="redisClusterConfiguration"></constructor-arg>

        <!-- 连接池配置信息 -->
        <property name="poolConfig" ref="jedisPoolConfig"></property>
    </bean>

    <!-- 如果没有设置序列化,则默认使用DefaultSerializer。
		 声明序列化组件
    -->
    <bean id="ss" class="org.springframework.data.redis.serializer.StringRedisSerializer" />
    <bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer" id="jacks" />
    <bean class="com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer" id="fast"></bean>

    <!-- RedisTemplate:核心组件 -->
    <bean id="redisTemplate02" class="org.springframework.data.redis.core.RedisTemplate"
          p:connectionFactory-ref="jedisConnectionFactory"
          p:keySerializer-ref="ss"
          p:hashKeySerializer-ref="ss"
          p:hashValueSerializer-ref="fast"
          p:stringSerializer-ref="ss"
          p:valueSerializer-ref="fast"></bean>


</beans>

如上就可将频繁从数据库中查询改为从缓存中查询数据 ,提高查询效率。

 

 

 

 

 

 

shiro-redis-spring-boot-starter是一个用于集成Apache ShiroRedis的Spring Boot Starter项目。Apache Shiro是一个强大而灵活的Java安全框架,用于身份验证、授权和会话管理等安全功能。而Redis是一个高性能的内存数据库,其具有快速的数据存取能力和持久化支持。 shiro-redis-spring-boot-starter提供了一种简化和快速集成ShiroRedis的方式,使得在Spring Boot应用中实现安全功能变得更加容易。通过使用该Starter,我们可以方便地将Shiro的会话管理功能存储到Redis中,从而支持分布式环境下的会话共享和管理。 使用shiro-redis-spring-boot-starter可以带来以下好处: 1. 分布式环境的会话共享:通过将Shiro的会话数据存储到Redis中,不同的应用节点可以共享同一个会话,从而实现分布式环境下的会话管理和跨节点的身份验证和授权。 2. 高可用性和性能:Redis作为一个高性能的内存数据库,具有出色的数据读写能力和持久化支持,可以提供可靠的会话存储和高性能的数据访问能力。 3. 简化配置和集成:shiro-redis-spring-boot-starter提供了封装好的配置和集成方式,减少了我们自己实现集成的复杂性和工作量。 总结来说,shiro-redis-spring-boot-starter为我们提供了一种简化和快速集成ShiroRedis的方式,使得在Spring Boot应用中实现安全功能变得更加容易和高效。通过它,我们可以实现分布式环境下的会话共享和管理,提供高可用性和性能的数据存取能力,同时简化了配置和集成的复杂性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值