使用Spring提供的缓存抽象机制整合EHCache为项目提供二级缓存
Spring自身并没有实现缓存解决方案,但是对缓存管理功能提供了声明式的支持,能够与多种流行的缓存实现进行集成。
Spring Cache是作用在方法上的(不能理解为只注解在方法上),其核心思想是:当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值存放在缓存中,等到下次利用同样的参数调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回。所以在使用Spring Cache的时候我们要保证我们的缓存的方法对于相同的方法参数要有相同的返回结果。
①适合
[1]经常被查询,很少或几乎不修改的[2]不是特别重要,允许出现偶尔的并发问题[3]不会被其他应用程序修改的
②不适合
[1]经常被修改[2]特别重要,不允许出现任何的并发问题,例如:财务数据[3]有可能被其他应用程序修改
①验证权限时查询的Res对象
Res getResByServletPath(String servletPath);
EngageService.PageInfo<Survey> getSurveyPage(Integer userId, boolean completed, Integer pageNum);EngageService.Survey getSurveyDeeply(Integer surveyId);
try {//1.尝试从缓存中获取数据Object value = cacheMap.get(key);//2.判断value是否为nullif(value == null){//3.实际执行目标方法value = 目标对象.目标方法();//4.将目标方法执行结果存入缓存cacheMap.put(key,value);}//5.返回valuereturn value;}catch(Exceptin e){}
int count = userService.getRegistUserCount(boolean active);
Cache Abstraction
①创建键生成器类,实现org.springframework.cache.interceptor.KeyGenerator接口
public class UserKeyGenerator implements KeyGenerator {
//命名方式:类名.方法名.参数名。。。
@Override
public Object generate(Object target, Method method, Object... params) {
//target:目标对象
//method:目标方法
//params:实参数组
StringBuilder bulider = new StringBuilder();
//获取目标对象名字
String name = target.getClass().getName();
bulider.append(".").append(name);
//获取方法的名字
String methodName = method.getName();
bulider.append(".").append(methodName);
//获取所有的参数
if(params!=null && params.length!=0){
for (int i = 0; i < params.length; i++) {
// Object object = params[i];
bulider.append(".").append(params[i]);
}
}
String key = bulider.substring(1);
System.out.println(key);
return key;
} }
2)需要在Spring配置文件中配置对应的bean
<bean id="userKeyGenerator" class="com.lamsey.survey.Ehcache.UserKeyGenerator"/>
[1]加入jar包[2]引入EHCache自身的配置文件,同时创建一个具名的缓存区域
<!-- Ehcache依赖 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.3</version>
</dependency>
</dependencies>
<!-- spring 整合ehcache -->
<!-- 自定义key生成器 -->
<bean id="userKeyGenerator" class="com.lamsey.survey.Ehcache.UserKeyGenerator"/>
<!-- 配置 EhCacheManagerFactoryBean工厂-->
<bean id="ehCacheManagerFactoryBean" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" >
<property name="configLocation" value="classpath:ehcache.xml"></property>
</bean>
<!-- 配置EhCacheCacheManager -->
<bean id="ehCacheCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" >
<property name="cacheManager" ref="ehCacheManagerFactoryBean"></property>
</bean>
<!--切面及切面表达式配置 -->
<aop:config>
<!-- 利用切面表达式找到切面切入点,进行切面编程 -->
<aop:pointcut expression="execution(* *..ResService.getResByServletPath(String))
or execution(* *..AnswerService.getSurveyPage(Integer, boolean, Integer))
or execution(* *..AnswerService.getSurveyDeeply(Integer))
or execution(* *..SurveyService.completedSurvey(Integer))" id="cachePointCut" />
<!-- 承上启下,得到切入点,同时连接处理的方法。对切入点进行处理(cache) -->
<!-- 缓存切面优先级高于数据库事务切面优先级 -->
<aop:advisor advice-ref="cacheAdvice" pointcut-ref="cachePointCut" order="1"/>
</aop:config>
<!-- 对切入点进行处理,这里表现为缓存 -->
<!-- 这里的自定义key【className.method.param1..paramn】 -->
<cache:advice id="cacheAdvice" cache-manager="ehCacheCacheManager" key-generator="userKeyGenerator">
<!-- 在cache属性中指定缓存区域的名称 -->
<!-- 指定要使用缓存的具体方法,要求必须是缓存切入点覆盖范围内的方法 -->
<cache:caching cache="surveyCache">
<cache:cacheable method=" getResByServletPath" />
<cache:cacheable method="getSurveyDeeply"/>
</cache:caching>
<!-- 使用另外一个有可能被清空数据的缓存区域 -->
<cache:caching cache="surveyCacheEvicable">
<cache:cacheable method="getSurveyPage" />
<!-- 执行updateSurveyCompleted方法时清空当前缓存区域 -->
<!-- 因为调查有可能更新,当更新后就需要进行重新获取参与调查 ,所以清空该缓存-->
<cache:cache-evict method="completedSurvey" all-entries="true" />
</cache:caching>
</cache:advice>
ehcache.xml(从hibernate复制出来)
<ehcache> <!-- Sets the path to the directory where cache .data files are created. If the path is a Java System Property it is replaced by
its value in the running VM. The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path -->
<!-- 默认以内存作为缓存,但如果不够,在这里设置一个电脑目录存储 -->
<diskStore path="java.io.tmpdir"/> <!--Default Cache configuration. These will applied to caches programmatically created through
the CacheManager. The following attributes are required for defaultCache: maxInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit. -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/> <!--Predefined caches. Add your cache configuration settings here.
If you do not have a configuration for your cache a WARNING will be issued when the
CacheManager starts The following attributes are required for defaultCache: name - Sets the name of the cache. This is used to identify the cache. It must be unique.
maxInMemory - Sets the maximum number of objects that will be created in memory
eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit. --> <!-- Sample cache named sampleCache1
This cache contains a maximum in memory of 10000 elements, and will expire
an element if it is idle for more than 5 minutes and lives for more than
10 minutes. If there are more than 10000 elements it will overflow to the
disk cache, which in this configuration will go to wherever java.io.tmp is
defined on your system. On a standard Linux system this will be /tmp"
-->
<cache name="surveyCache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true"
/> <!-- Sample cache named sampleCache2
This cache contains 1000 elements. Elements will always be held in memory.
They are not expired. -->
<cache name="surveyCacheEvicable"
maxElementsInMemory="1000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/> --> <!-- Place configuration for your caches following --> </ehcache>
<!-- 缓存切面优先级高于数据库事务切面优先级 -->
缓存切面在外层,事务切面在内层
结论:为了减少不必要的事务操作让缓存切面的优先级高于事务切面的优先级。

7.配置二级缓存
①创建键生成器,实现KeyGenerator接口
②引入EHCache环境
[1]引入EHCache依赖
[2]引入EHCache自身配置文件
[3]在EHCache中创建两个具名的缓存区域
(1)不清空的
(2)可清空的
③在Spring配置文件中配置缓存抽象和EHCache的整合
[1]配置缓存管理器工厂
[2]配置缓存管理器
[3]配置缓存切面的切入点表达式
execution(* *..ResService.getResByServletPath(String)) or
execution(* *..EngageService.getSurveyPage(..)) or
execution(* *..EngageService.getSurveyDeeply(..)) or
execution(* *..SurveyService.updateSurveyCompleted(..))
[4]配置缓存切面的通知:装配缓存管理器、装配键生成器、指定id
引用具体的缓存区域
用cache:cacheable标签指定要缓存数据的方法
用cache:cache-evict标签指定导致缓存清空的方法
[5]用aop:advisor将切入点表达式和缓存通知关联起来
④设置切面优先级让缓存切面优先级高于事务切面
使用Spring提供的缓存抽象机制整合EHCache为项目提供二级缓存的更多相关文章
- 7.4mybatis整合ehcache(mybatis无法实现分布式缓存必须和其他缓存框架整合)
<\mybatis\day02\14查询缓存-二级缓存-整合ehcache.av> mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache-- 这里有做本 ...
- Spring源码-IOC部分-循环依赖-用实例证明去掉二级缓存会出现什么问题【7】
实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...
- Hibernate二级缓存简述及基于Spring4,Hibernate5,Ehcache3的二级缓存配置
Hibernate L2缓存 缓存的分类 L2缓存工作原理 放入二级缓存的数据 Ehcache 依赖 ehcache.xml 常用的memoryStoreEvictionPolicy(缓存算法) eh ...
- java框架之SpringBoot(11)-缓存抽象及整合Redis
Spring缓存抽象 介绍 Spring 从 3.1 版本开始定义了 org.springframework.cache.Cache 和 org.springframework.cache.Cache ...
- ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存
ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存 hibernate : Hibernate是一个持久层框架,经常访问物理数据库 ...
- mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache
1.1 什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 一级缓存是SqlSession级别的缓存.在操作数据库时需要构造 s ...
- Mybatis整合(Redis、Ehcache)实现二级缓存
目的: Mybatis整合Ehcache实现二级缓存 Mybatis整合Redis实现二级缓存 Mybatis整合ehcache实现二级缓存 ssm中整合ehcache 在POM中导入相关依赖 < ...
- Mybatis学习(五)————— 延迟加载和缓存机制(一级二级缓存)
一.延迟加载 延迟加载就是懒加载,先去查询主表信息,如果用到从表的数据的话,再去查询从表的信息,也就是如果没用到从表的数据的话,就不查询从表的信息.所以这就是突出了懒这个特点.真是懒啊. Mybati ...
- Mybatis(五) 延迟加载和缓存机制(一级二级缓存)
踏踏实实踏踏实实,开开心心,开心是一天不开心也是一天,路漫漫其修远兮. --WH 一.延迟加载 延迟加载就是懒加载,先去查询主表信息,如果用到从表的数据的话,再去查询从表的信息,也就是如果没用到从表的 ...
随机推荐
- MyCat不适用场景(使用时避免)
1.非分片字段查询 Mycat中的路由结果是通过分片字段和分片方法来确定的.例如下图中的一个Mycat分库方案: · 根据 tt_waybill 表的 id 字段来进行分片 · ...
- 基于Redis的INCR实现一个限流器
模式:计数器 计数器是 Redis 的原子性自增操作可实现的最直观的模式了,它的想法相当简单:每当某个操作发生时,向 Redis 发送一个 INCR 命令. 比如在一个 web 应用程序中,如果想知道 ...
- Arduino IDE for ESP8266 项目云盒子 (1)AP直接模式
手机直接连接esp8266辐射的WIFI,通信. https://item.taobao.com/item.htm?spm=a230r.1.14.20.eYblO3&id=5219451024 ...
- 2017-2018-2 20155314《网络对抗技术》Exp6 信息搜集与漏洞扫描
2017-2018-2 20155314<网络对抗技术>Exp6 信息搜集与漏洞扫描 目录 实验目标 实验内容 实验环境 基础问题回答 预备知识 实验步骤 1 信息搜集 1.1 外围信息搜 ...
- ECharts.js学习动态数据绑定
https://my.oschina.net/brillantzhao/blog/1541702https://www.cnblogs.com/leoxuan/p/6513591.htmlhttps: ...
- B轮公司技术问题列表(转)
1.异构系统的接口对接我们有自己的一套统一接口,但是需要与其它公司的接口做对接,但是各个公司的接口各不相同,有什么好的方式能够方便与各公司的接口做对接的同时我们这边也能尽量少或者不需要改动代码就能实现 ...
- zabbix学习-zabbix安装
本次安装教程完全参考官方rpm安装教程: https://www.zabbix.com/documentation/3.4/zh/manual/installation/install_from_pa ...
- 安装win10操作系统的设备将要突破10亿台
导读 该公司最初的目标是在发布后的三年内在 10 亿台设备上运行 Windows 10. 据微软高管梅赫迪 (Yusuf Mehdi) 周四在 Twitter 上透露,目前已经有 8 亿多台设备安装了 ...
- TerraGate软件安装后,不能启动的解决办法
在服务端安装Skyline的TerraGate软件的时候,大家可能会遇到过这样的问题,“TerraGate软件安装后,不能启动”,很多时候,这个问题是因为TerraGate设 置的端口号已经被占用造成 ...
- Java多线程编程模式实战指南一:Active Object模式(下)
Active Object模式的评价与实现考量 Active Object模式通过将方法的调用与执行分离,实现了异步编程.有利于提高并发性,从而提高系统的吞吐率. Active Object模式还有个 ...