Spring Boot学习分享(六)——整合shiro+ehcahce


SpringBoot+ehcache+shiro的实现以及遇到的坑


简单介绍一下ehcache:
ehcache是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认CacheProvider。
优点:EHcache直接在jvm虚拟机中缓存,速度快,效率高;
缺点:但是缓存共享麻烦,集群分布式应用不方便。


使用ehcache进行数据缓存,并且将ehcache整合到shiro,由于shiro本身就提供了对ehcache的支持,所以整合起来十分简单


下面是spring项目整合所需的配置文件:

   <!-- 缓存配置  -->
    <bean id="ehCacheManager"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache/ehcache.xml" />
    </bean>

    <!-- shiro封装cacheManager -->
    <bean id="shiroCacheManager"
        class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManager" ref="ehCacheManager" />
    </bean>

    <!-- spring 封装ehcache缓存管理器  -->
    <bean id="springCacheManager"
        class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <property name="cacheManager" ref="ehCacheManager" />
    </bean>

    <!-- 激活spring 缓存注解 -->
    <cache:annotation-driven cache-manager="springCacheManager"/>

而使用Spring Boot则须将上面的配置自己通过配置类实现:

shiro的缓存实现(ShiroConfiguration.class),这里只有缓存管理器的实现,具体代码可参照Spring Boot学习分享(二)这篇文章

    /**
     * @param cm EHcache工厂bean
     * @return shiro的缓存管理器
     */
    @Bean(name = "cacheManagerShiro")
    public CacheManager cacheManagerShiro(@Qualifier("ehcacheManager") EhCacheManagerFactoryBean cm) {
        EhCacheManager cacheManagershiro = new EhCacheManager();
        cacheManagershiro.setCacheManager(cm.getObject());
        return cacheManagershiro;
    }

spring的ehcache缓存实现(SpringConfiguration .class):

@Configuration
public class SpringConfiguration {

    /**
     * @return ehcache工厂实例
     */
    @Bean(name = "ehcacheManager")
    public EhCacheManagerFactoryBean cacheManager() {
        EhCacheManagerFactoryBean cacheManager = new EhCacheManagerFactoryBean();
        //配置路径使用classpath加载
        cacheManager.setConfigLocation(new ClassPathResource("ehcache/ehcache.xml"));
        cacheManager.setShared(true);//单例模式
        return cacheManager;
    }

    /**
     * @param cm ehcache工廠的实例
     * @return spring的缓存管理器
     */
    @Bean(name = "cacheManagerSpring")
    public EhCacheCacheManager cacheManagerSpring(
            @Qualifier("ehcacheManager") EhCacheManagerFactoryBean cm) {
        EhCacheCacheManager cacheManager = new EhCacheCacheManager()
        cacheManager.setCacheManager(cm.getObject());
        return cacheManager;
    }
}

代码基本上按照配置文件转化来,也有其它的实现方案,这里就不多赘述


重点来了

博主在整合的时候遇到了一个bug,博主在服务层的实现类中使用了spring缓存注解,但是,特么一部分类的注解生效,一部分类的注解不生效不生效不生效。。。
最后发现了一篇帖子
大概意思是由于shiro的自定义的Realm类自动注入十分的早,导致里面自动注入的服务层接口的属性还没添加就已经被注入,这就是部分类的缓存注解不生效的原因,而解决方法,也异常的简单,只要在注入的接口上加一个@Lazy标签,让这个接口迟一点加载就可以了。。。


下面附上ehcache的配置文件样例:
ehcache.xml:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://www.ehcache.org/ehcache.xsd">

    <diskStore path="java.io.tmpdir/ehcache"/>

    <!-- 默认缓存 -->
    <defaultCache
            maxElementsInMemory="1000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"/>

    <!-- 
        配置自定义缓存
        maxElementsInMemory:缓存中允许创建的最大对象数
        eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
        timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,
        两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效,
        如果该值是 0 就意味着元素可以停顿无穷长的时间。
        timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,
        这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
        overflowToDisk:内存不足时,是否启用磁盘缓存。
        memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。
    -->
    <!-- userService查询用户的缓存 -->
    <!--缓存用户的信息 -->
    <cache name="User"
           maxElementsInMemory="2000"
           eternal="false"
           timeToIdleSeconds="3000"
           timeToLiveSeconds="30000"
           overflowToDisk="false"
           memoryStoreEvictionPolicy="LRU"/>
    <!-- 密码尝试次数的缓存 -->
    <cache name="passwordRetryCache"
           maxElementsInMemory="2000"
           eternal="false"
           timeToIdleSeconds="60"
           timeToLiveSeconds="60"
           overflowToDisk="false"
           statistics="true">
    </cache>
</ehcache>

猜你喜欢

转载自blog.csdn.net/madonghyu/article/details/79885223