Shiro整合EhCache

缓存工具EhCache

EhCache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。可以和大部分Java项目无缝整合,例如:Hibernate中的缓存就是基于EhCache实现的。EhCache支持内存和磁盘存储,默认存储在内存中,如内存不够时把缓存数据同步到磁盘中。EhCache支持基于Filter的Cache实现,也支持Gzip压缩算法。 EhCache直接在JVM虚拟机中缓存,速度快,效率高;EhCache缺点是缓存共享麻烦,集群分布式应用使用不方便

添加依赖

<dependency>
 <groupId>net.sf.ehcache</groupId>
 <artifactId>ehcache</artifactId>
 <version>2.6.11</version>
 <type>pom</type>
</dependency>

添加配置文件 ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <!--磁盘的缓存位置-->
    <diskStore path="java.io.tmpdir/ehcache"/>
    <!--默认缓存-->
    <defaultCache
            maxEntriesLocalHeap="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxEntriesLocalDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>
    <!--helloworld 缓存-->
    <cache name="HelloWorldCache"
           maxElementsInMemory="1000"
           eternal="false"
           timeToIdleSeconds="5"
           timeToLiveSeconds="5"
           overflowToDisk="false"
           memoryStoreEvictionPolicy="LRU"/>
    <!--
    defaultCache:默认缓存策略,当 ehcache 找不到定义的缓存时,则使用这个
   缓存策略。只能定义一个。
    -->
    <!--
    name:缓存名称。
    maxElementsInMemory:缓存最大数目
    maxElementsOnDisk:硬盘最大缓存个数。
    eternal:对象是否永久有效,一但设置了,timeout 将不起作用。
    overflowToDisk:是否保存到磁盘,当系统宕机时
    timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当
   eternal=false 对象不是永久有效时使用,可选属性,默认值是 0,也就是可闲置时间
   无穷大。
    timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间
   介于创建时间和失效时间之间。仅当 eternal=false 对象不是永久有效时使用,默认
   是 0.,也就是对象存活时间无穷大。
    diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store
   persists between restarts of the Virtual Machine. The default value
   is false.
    diskSpoolBufferSizeMB:这个参数设置 DiskStore(磁盘缓存)的缓存区大
   小。默认是 30MB。每个 Cache 都应该有自己的一个缓冲区。
    diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是
   120 秒。
    memoryStoreEvictionPolicy:当达到 maxElementsInMemory 限制时,
   Ehcache 将会根据指定的策略去清理内存。默认策略是 LRU(最近最少使用)。你可以
   设置为 FIFO(先进先出)或是 LFU(较少使用)。
    clearOnFlush:内存数量最大时是否清除。
    memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策
   略)、FIFO(先进先出)、LFU(最少访问次数)。
    FIFO,first in first out,这个是大家最熟的,先进先出。
    LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是
   讲一直以来最少被使用的。如上面所讲,缓存的元素有一个 hit 属性,hit 值最小的将
   会被清出缓存。
    LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当
   缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳
   离当前时间最远的元素将被清出缓存。
    -->
</ehcache>

测试

创建测试类,操作缓存
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

import java.io.InputStream;

public class TestEH {
  public static void main(String[] args) {
     //获取编译目录下的资源的流对象
     InputStream input = TestEH.class.getClassLoader().getResourceAsStream("ehcache.xml");
     //获取 EhCache 的缓存管理对象
     CacheManager cacheManager = new CacheManager(input);
     //获取缓存对象
     Cache cache = cacheManager.getCache("HelloWorldCache");
     //创建缓存数据
     Element element = new Element("name","zhang3");
     //存入缓存
     cache.put(element);
     //从缓存中取出
     Element element1 = cache.get("name");
     System.out.println(element1.getObjectValue());
  }
}

Shiro整合EhCache 

Shiro官方提供了shiro-ehcache,实现了整合EhCache作为Shiro的缓存工具。可以缓存认证执行的Realm方法,减少对数据库的访问,提高认证效率。
SpringBoot整合Shiro: SpringBoot整合Shiro-CSDN博客

添加依赖

<!--Shiro 整合 EhCache-->
<dependency>
 <groupId>org.apache.shiro</groupId>
 <artifactId>shiro-ehcache</artifactId>
 <version>1.4.2</version>
</dependency>
<dependency>
 <groupId>commons-io</groupId>
 <artifactId>commons-io</artifactId>
 <version>2.6</version>
</dependency>

添加配置文件

在 resources 下添加配置文件 ehcache/ ehcache-shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache name="ehcache" updateCheck="false">
    <!--磁盘的缓存位置-->
    <diskStore path="java.io.tmpdir"/>
    <!--默认缓存-->
    <defaultCache
            maxEntriesLocalHeap="1000"
            eternal="false"
            timeToIdleSeconds="3600"
            timeToLiveSeconds="3600"
            overflowToDisk="false">
    </defaultCache>
    <!--登录认证信息缓存:缓存用户角色权限-->
    <cache name="loginRolePsCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true"/>
</ehcache>

修改配置类

修改配置类 ShiroConfig

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import com.example.demo.component.MyRealm;
import net.sf.ehcache.CacheManager;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;

import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.io.ResourceUtils;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.io.InputStream;

@Configuration
public class ShiroConfig {
      @Autowired
      private MyRealm myRealm;

    //配置 SecurityManager
    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(){
        //1 创建 defaultWebSecurityManager 对象
        DefaultWebSecurityManager defaultWebSecurityManager = new
                DefaultWebSecurityManager();
        //2 创建加密对象,并设置相关属性
        HashedCredentialsMatcher matcher = new
                HashedCredentialsMatcher();
        //2.1 采用 md5 加密
        matcher.setHashAlgorithmName("md5");
        //2.2 迭代加密次数
        matcher.setHashIterations(3);
        //3 将加密对象存储到 myRealm 中
        myRealm.setCredentialsMatcher(matcher);
        //4 将 myRealm 存入 defaultWebSecurityManager 对象
        defaultWebSecurityManager.setRealm(myRealm);
        //4.5 设置 rememberMe

        defaultWebSecurityManager.setRememberMeManager(rememberMeManager());
        //4.6 设置缓存管理器
        defaultWebSecurityManager.setCacheManager(getEhCacheManager());
        //5 返回
        return defaultWebSecurityManager;
    }
    //缓存管理器
    public EhCacheManager getEhCacheManager(){
        EhCacheManager ehCacheManager = new EhCacheManager();
        InputStream is = null;
        try {
            is = ResourceUtils.getInputStreamForPath(
                    "classpath:ehcache/ehcache-shiro.xml");
        } catch (IOException e) {
            e.printStackTrace();
        }
        CacheManager cacheManager = new CacheManager(is);
        ehCacheManager.setCacheManager(cacheManager);
        return ehCacheManager;
    }
    //cookie 属性设置
    public SimpleCookie rememberMeCookie(){
        SimpleCookie cookie = new SimpleCookie("rememberMe");
        //设置跨域
        //cookie.setDomain(domain);
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        cookie.setMaxAge(30*24*60*60);
        return cookie;
    }
    //创建 Shiro 的 cookie 管理对象
    public CookieRememberMeManager rememberMeManager(){
        CookieRememberMeManager cookieRememberMeManager = new
                CookieRememberMeManager();
        cookieRememberMeManager.setCookie(rememberMeCookie());

        cookieRememberMeManager.setCipherKey("1234567890987654".getBytes());
        return cookieRememberMeManager;
    }

    @Bean
    public static DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator(){

        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator=new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setUsePrefix(true);

        return defaultAdvisorAutoProxyCreator;
    }
    //配置 Shiro 内置过滤器拦截范围
    @Bean
    public DefaultShiroFilterChainDefinition shiroFilterChainDefinition(){

        DefaultShiroFilterChainDefinition definition = new DefaultShiroFilterChainDefinition();
        //设置不认证可以访问的资源
        definition.addPathDefinition("/myController/userLogin", "anon");
        definition.addPathDefinition("/myController/login","anon");
        //配置登出过滤器
        definition.addPathDefinition("/logout","logout");
        //设置需要进行登录认证的拦截范围
        definition.addPathDefinition("/**","authc");

        //添加存在用户的过滤器(rememberMe)
        definition.addPathDefinition("/**","user");
        return definition;
    }
    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }
}

测试

第一次登录可以看到查询角色、权限信息

 

先清除日志,再点击角色认证、权限认证,查看日志,没有查询数据库。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Shiro可以很方便地与Memcached进行整合,以实现Session的存储和管理。 下面是整合步骤: 1. 首先需要添加Memcached的相关依赖,可以使用Maven来管理依赖,添加以下代码到pom.xml文件中: ```xml <dependency> <groupId>com.whalin</groupId> <artifactId>Memcached-Java-Client</artifactId> <version>3.0.2</version> </dependency> ``` 2. 在Shiro的配置文件(shiro.ini或shiro.yml)中配置Session的管理方式为Memcached,例如: ```ini [main] cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager [session] sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager sessionManager.globalSessionTimeout = 1800000 sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO sessionDAO.activeSessionsCacheName = shiro-activeSessionCache cacheManager = org.apache.shiro.cache.ehcache.EhCacheManager securityManager.cacheManager = $cacheManager # Memcached session # ======================================= sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO sessionDAO.activeSessionsCacheName = shiro-activeSessionCache sessionDAO.sessionIdGenerator = org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator cacheManager = com.whalin.MemCached.MemCachedClientPoolCacheManager cacheManager.poolName = shiroCache cacheManager.servers = 127.0.0.1:11211 securityManager.cacheManager = $cacheManager sessionManager.sessionDAO = $sessionDAO sessionManager.cacheManager = $cacheManager ``` 其中,cacheManager配置使用了MemoryConstrainedCacheManager和EhCacheManager,用于缓存Shiro的授权信息和其他缓存数据;sessionDAO配置使用了EnterpriseCacheSessionDAO,用于管理Session的存储和读取;cacheManager配置使用了MemCachedClientPoolCacheManager,用于与Memcached进行交互。 3. 在项目启动时,需要创建Memcached客户端并将其注入到cacheManager中,例如: ```java import com.whalin.MemCached.MemCachedClient; import com.whalin.MemCached.SockIOPool; public class MemcachedCacheManager implements CacheManager { private MemCachedClient cache; @Override public <K, V> Cache<K, V> getCache(String name) throws CacheException { return new MemcachedCache<>(name, this.cache); } public void init() { String[] servers = {"127.0.0.1:11211"}; SockIOPool pool = SockIOPool.getInstance("shiroCache"); pool.setServers(servers); pool.initialize(); this.cache = new MemCachedClient("shiroCache"); } public void destroy() { SockIOPool.getInstance("shiroCache").shutDown(); } } ``` 4. 在Web应用中,可以使用DefaultWebSessionManager来管理Session,例如: ```java import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; public class MemcachedSessionManager extends DefaultWebSessionManager { @Override protected void onStart(Session session, SessionContext context) { super.onStart(session, context); // 将Session存储到Memcached中 this.getSessionDAO().create(session); } @Override protected void onStop(Session session, SessionKey key) { super.onStop(session, key); // 从Memcached中删除Session this.getSessionDAO().delete(session); } @Override protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException { // 从Memcached中读取Session Session session = this.getSessionDAO().readSession(sessionKey); if (session == null) { throw new UnknownSessionException("Session not found with key: " + sessionKey); } return session; } } ``` 通过以上步骤,就可以将Java Shiro与Memcached整合起来,实现Session的存储和管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值