当前位置:首页 > Java > 正文内容

Ehcache缓存简单使用

flowstone8年前 (2017-11-25)Java506

SPRING整合EHCACHE

1.引入坐标

pom.xml


<!-- ehcache的缓存框架 -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache-core</artifactId>
    <version>2.6.10</version>
</dependency>
<!-- spring整合第三方框架的 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>${spring.version}</version>
</dependency>


2.配置Ehcache

ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <!-- 硬盘上缓存的临时目录 -->
    <diskStore path="java.io.tmpdir"/>
    <!-- 
    maxElementsInMemory:内存中最大存放的元素的个数
    eternal:是否永生,默认是false
    timeToIdleSeconds:发呆闲置的时间,超过该时间,被清除,单位秒
    timeToLiveSeconds:存活的事件,超过该时间被清除
    maxElementsOnDisk:如果内存满了,溢出到硬盘上的临时目录中的存放的元素的个数
    diskExpiryThreadIntervalSeconds:轮询时间,巡视组
    memoryStoreEvictionPolicy:内存对象的清理策略,如果满了,怎么办?
    策略有三个:LRU、LFU、FIFO
    LRU:最少使用被清理,次数
    LFU:时间,闲置最长的时间
    FIFO:管道策略,先进先出
     -->

    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>
    <!-- Spring整合的菜单缓存 -->
     <cache name="project_menu_cache"
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </cache>
</ehcache>


3.配置Spring整合Ehcache

applicationContext-cache.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:cache="http://www.springframework.org/schema/cache"
    xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
    <!-- 配置ehcache的对象EhCacheManager -->
    <bean id="ehCacheManager"
        class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <!-- 注入ehcache核心配置文件的位置 Default is "ehcache.xml" in the root of the 
            class path, or if not found, "ehcache-failsafe.xml" in the EhCache jar (default 
            EhCache initialization). 可以不配置,默认找类路径下的ehcache.xml -->
        <property name="configLocation" value="classpath:ehcache.xml" />
    </bean>
    <!-- Spring整合Ehache -->
    <!-- Spring的平台缓存管理器 -->
    <bean id="springCacheManager"
        class="org.springframework.cache.ehcache.EhCacheCacheManager">
        <!-- 注入ehcache的对象 -->
        <property name="cacheManager" ref="ehCacheManager"></property>
    </bean>
    <!-- spring的缓存注解驱动 -->
    <cache:annotation-driven cache-manager="springCacheManager" />
</beans>


4.在需要操作缓存数据的方法上添加注解

保存缓存

@Cacheable(value=”cache”) //要缓存查询的结果到Ehchache中,参数是缓存区域

清除缓存

@CacheEvict(value=”cache”,allEntries=true) //

SHIRO整合EHCACHE

1.引入ehcache,配置ehcache

ehcache.xml

<!-- Shiro权限缓存-认证 -->
    <cache name="project_realm_authentication_cache"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        maxElementsOnDisk="10000000"
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
    <persistence strategy="localTempSwap"/>
</cache>
<!-- Shiro权限缓存-授权 -->
    <cache name="project_realm_authorization_cache"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        maxElementsOnDisk="10000000"
        diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU">
    <persistence strategy="localTempSwap"/>
</cache>


2.shiro整合ehchache

pom.xml

<!-- shiro整合ehcache -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>1.3.2</version>
</dependency>


3.spring中配置ehcache缓存

applicationContext-shiro.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"
    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/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/data/jpa 
        http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <!-- 配置Shiro核心Filter  --> 
    <bean id="shiroFilter" 
        class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <!-- 安全管理器 -->
        <property name="securityManager" ref="securityManager" />
        <!-- 未认证,跳转到哪个页面  -->
        <property name="loginUrl" value="/login.html" />
        <!-- 登录页面页面 -->
        <property name="successUrl" value="/index.html" />
        <!-- 认证后,没有权限跳转页面 -->
        <property name="unauthorizedUrl" value="/unauthorized.html" />
        <!-- shiro URL控制过滤器规则  -->
        <property name="filterChainDefinitions">
            <value>
                /login.html* = anon
                /user_login.action* = anon 
                /validatecode.jsp* = anon
                /css/** = anon
                /js/** = anon
                /images/** = anon
                /services/** = anon 
                /pages/base/courier.html* = perms[courier:list]
                /pages/base/area.html* = roles[base]
                /** = authc
            </value>
        </property>
    </bean>
    <!-- 安全管理器  -->
    <bean id="securityManager" 
        class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <!-- 注入自定义realm -->
        <property name="realm" ref="bosRealm"></property>
        <!-- 开启Shiro缓存功能,需要在shiro安全管理器中注入shiro的 平台缓存管理器 -->
        <property name="cacheManager" ref="shiroCacheManager" />
    </bean>

    <!-- 配置Shiro的bean后处理器:用来初始化Shiro的bean在spring中-->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
    <!-- 开启Shiro注解 -->
    <!-- Enable Shiro Annotations for Spring-configured beans.
    Only run after -->
    <!-- the lifecycleBeanProcessor has run:
    depends-on:当前bean初始化时,必须依赖于指定的bean,(指定的
    bean必须先初始化)
    下面的两个bean配置:传统的aop编程:增强、切点、切面
    -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
    depends-on="lifecycleBeanPostProcessor"/>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <!-- 必须注入安全管理器 -->
        <property name="securityManager" ref="securityManager" />
    </bean>

    <!-- shiro整合echcache的缓存配置 -->
    <!-- 配置Shiro的平台缓存管理 -->
    <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <!-- 注入ehcache的对象 -->
        <property name="cacheManager" ref="ehCacheManager" />
    </bean>

</beans>


4.在reaml对象中指定缓存权限的数据的区域

package me.xueyao.project.realms;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import me.xueyao.project.dao.system.PermissionRepository;
import me.xueyao.project.dao.system.RoleRepository;
import me.xueyao.project.dao.system.UserRepository;
import me.xueyao.project.domain.system.Permission;
import me.xueyao.project.domain.system.Role;
import me.xueyao.project.domain.system.User;

@Component("projectRealm")
public class ProjectRealm extends AuthorizingRealm{

    //只需要向父类注入缓存域即可
    //认证缓存区域
    @Value("project_realm_authentication_cache")
    //方法注入按照参数注入和方法名无关
    public void setSuperAuthenticationCacheName(String authenticationCacheName) {
        super.setAuthenticationCacheName(authenticationCacheName);
    }

    //授权缓存区域
    @Value("project_realm_authorization_cache")
    public void setSuperauthorizationCacheName(String authorizationCacheName){
        super.setAuthorizationCacheName(authorizationCacheName);
    }
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private PermissionRepository permissionRepository;

    //提供授权数据
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // TODO Auto-generated method stub
        System.out.println("授权数据提供中...");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //写死安全数据
        //添加功能权限:底层是set集合
        //authorizationInfo.addStringPermission("courier:list");
        //添加角色权限
        //authorizationInfo.addRole("base");

        //2.根据登录用户动态获取授权数据 
        //方法一
        //User user = (User)SecurityUtils.getSubject().getPrincipal();
        //方法二
        User user = (User)principals.getPrimaryPrincipal();
        //判断是否是管理员
        if ("admin".equals(user.getUsername())) {

            for (Role role :roleRepository.findAll()) {
                //添加角色
                authorizationInfo.addRole(role.getKeyword());
            }

            for (Permission permission : permissionRepository.findAll()) {
                //添加功能权限
                authorizationInfo.addStringPermission(permission.getKeyword());
            }
        } else {
            //不是管理员
            for (Role role : roleRepository.findByUsers(user)) {
                //添加角色
                authorizationInfo.addRole(role.getKeyword());

                //添加角色具有的权限
                for (Permission permission : role.getPermissions()) { //此处涉及持久态问题,只有持久态后才可以查询 
                    authorizationInfo.addStringPermission(permission.getKeyword());
                }
            }
        }
        return authorizationInfo;
    }

    //提供认证数据
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 目标:根据用户名查询用户对象,封装成认证信息对象,返回交给安全管理器
        //用户名
        String username = ((UsernamePasswordToken)token).getUsername();
        //查询数据库:根据用户查询 对象
        User user = userRepository.findByUsername(username);
        //判断
        if (null == user) {
            //如果返回null,安全管理器认为用户名不存在
            return null;
        } else {
            //用户名存在,将用户信息封装到认证信息对象中,交给安全管理器
            /**
             * @param1 principal 负责人,就是用户对象,以后会保存到session中
             * @param2 credential 凭证,这里就是真实的密码
             * @param3 realm的对象的一个唯一的名字,类似uuid,底层就是一个随机数
             */
            SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), super.getName());
            return authenticationInfo;
        }
    }

}


扫描二维码推送至手机访问。

版权声明:本文由薛尧的博客发布,如需转载请注明出处。

本文链接:https://flowstone.sourceforge.io/?id=21

分享给朋友:

相关文章

Java编程思想学习总结一(一切都是对象)

存储位置寄存器堆栈 存储对象引用,堆栈指针向下移动,分配新的内存,向上移动,释放内存堆 存储Java对象常量存储 存储常量值非RAM存储 存储流对象和持久化对象基本类型所占存储空间基本类型大小包装器类型默认值boolean16bitBool...

Java多线程-线程状态

线程状态6个状态定义:java.lang.Thread.StateNew: 尚未启动的线程的线程状态。Runnable: 可运行线程的线程状态,等待CPU调度。Blocked: 线程阻塞等待监视器锁定的线程状态。处于synchronized...

Java多线程-线程中止

不正确的线程中止-StopStop:中止线程,并且清除监控器锁的信息,但是可能导致 线程安全问题,JDK不建议用。 Destroy: JDK未实现该方法。/**  * @author simon  ...

CPU缓存和内存屏障

CPU性能优化手段-缓存为了提高程序运行的性能,现代CPU在很多方面对程序进行了优化。例如:CPU高速缓存。尽可能地避免处理器访问主内存的时间开销,处理器大多会利用缓存(cache)以提高性能。多级缓存L1 Cache(一级缓存)是CPU第...

代码优化-多态代替IF条件判断

场景描述在开发的场景中,常常会遇到打折的业务需求,每个用户对应的等级,他们的打折情况也是不一样的。例如普通会员打9折,青铜会员打8.5折,黄金会员打8折等等。在一般开发中最简单的就是判断用户的等级,然后对订单作对应的打折处理。场景示例写了一...

JPA使用-实体类上常用注解

@SQLDelete场景描述JPA中提供了简单的CRUD操作,其中删除操作是物理删除,但是实际应用中,系统中的数据是一种资源,不能直接删除,应该做到逻辑删除,JPA中删除操作是不可取的。场景示例调用JPA的删除方法,如下代码所示:@Test...