在Spring中使用cache(EhCache的对象缓存和页面缓存)
Spring框架从version3.1开始支持cache,并在version4.1版本中对cache功能进行了增强。
spring cache 的关键原理就是 spring AOP,通过 spring AOP,其实现了在方法调用前、调用后获取方法的入参和返回值,进而实现了缓存的逻辑。关于Spring Cache原理的详细介绍,参见http://blog.csdn.net/guugle2010/article/details/40115675
1、采用Spring的默认开箱即用的cache(Out of the box)
采用Spring开箱即用的Cache,必须加载spring-context.jar包。
不支持高可用性,也不具备持久化数据能力(只能read)并发不好。
1.1 在方法上使用注解
| @Cacheable | 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 | |
|---|---|---|
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如: @Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} |
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如: @Cacheable(value=”testcache”,key=”#userName”) |
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | 例如: @Cacheable(value=”testcache”,condition=”#userName.length()>2”) |
| @CachePut | 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用 | |
|---|---|---|
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如: @CachePut(value=”mycache”) 或者 @CachePut(value={”cache1”,”cache2”} |
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如: @CachePut(value=”testcache”,key=”#userName”) |
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 | 例如: @CachePut(value=”testcache”,condition=”#userName.length()>2”) |
| @CachEvict | 主要针对方法配置,能够根据一定的条件对缓存进行清空 | |
|---|---|---|
| value | 缓存的名称,在 spring 配置文件中定义,必须指定至少一个 | 例如: @CachEvict(value=”mycache”) 或者 @CachEvict(value={”cache1”,”cache2”} |
| key | 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 | 例如: @CachEvict(value=”testcache”,key=”#userName”) |
| condition | 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 | 例如: @CachEvict(value=”testcache”, condition=”#userName.length()>2”) |
| allEntries | 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 | 例如: @CachEvict(value=”testcache”,allEntries=true) |
| beforeInvocation | 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 | 例如: @CachEvict(value=”testcache”,beforeInvocation=true) |
@Caching
@CacheConfig
默认的key生成器策略KeyGenerator
If no params are given, return SimpleKey.EMPTY.
If only one param is given, return that instance.
If more the one param is given, return a SimpleKey containing all parameters.
1.2 基于XML的配置
<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">
<context:component-scan base-package="com.traveller.domain.cache"/>
<context:annotation-config/>
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<property name="name" value="default"/>
</bean>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<property name="name" value="ascenceCache"/>
</bean>
</set>
</property>
</bean>
</beans>
1.3 基于配置类的配置
@Configuration
@EnableCaching
public class CacheConfig implements CachingConfigurer {
@Bean
@Override
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager(); cacheManager.setCaches(Arrays.asList(
new ConcurrentMapCache("scenceCache"),
new ConcurrentMapCache("userCache"))); return cacheManager;
}
......
}
参考:
http://www.cnblogs.com/rollenholt/p/4202631.html
https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html
2、EHCache 集成
Ehcache从 Hibernate发展而来,逐渐涵盖了Cahce界的全部功能,是目前发展势头最好的一个项目。
Ehcache可以对页面、对象、数据进行缓存,同时支持集群/分布式缓存,具有快速,简单,低消耗,依赖性小,扩展性强的特点;支持对象或序列化缓存,支持缓存或元素的失效,提供LRU、LFU和FIFO淘汰算法,支持内存缓存和磁盘缓存等特点。
Spirng集成ehCache,需要spring-context-support.jar包的支持。
FIFO,first in first out,这个是大家最熟的,先进先出。
LFU, Less Frequently Used,直白一点就是讲一直以来最少被使用的。缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
2.1 基于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:cache="http://www.springframework.org/schema/cache"
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.2.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd"> <cache:annotation-driven cache-manager="cacheManager" /> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="cacheManagerFactory" /> <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache.xml" p:shared="false" />
</beans>
2.2 基于配置类的配置
@Configuration
@EnableCaching
public class CacheConfig implements CachingConfigurer {
@Bean
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
return ehCacheManagerFactoryBean;
} @Bean
public CacheManager cacheManager() {
EhCacheCacheManager cacheManager = new EhCacheCacheManager();
cacheManager.setCacheManager(ehCacheManagerFactoryBean().getObject());
return cacheManager;
}
}
2.3 ehcache.xml的配置
To learn how to configure Ehcache, read this official ehcache.xml example.
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
monitoring="autodetect">
<!-- <diskStore path="java.io.tmpdir" /> -->
<diskStore path="E:/cachetmpdir"/>
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
maxElementsOnDisk="10000000" diskPersistent="false"
diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <cache name="scenceCache" maxElementsInMemory="10000"
maxElementsOnDisk="1000" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU" />
</ehcache>
maxElementsInMemory: 缓存最大数目
eternal: 缓存是否持久
timeToIdleSeconds: 当缓存闲置n秒后销毁
timeToLiveSeconds: 当缓存存活n秒后销毁
overflowToDisk: 是否保存到磁盘,当系统宕机时
2.4 测试
In non-web application, you need to shut down the Spring context manually, so that Ehcache got chance to shut down as well, otherwise Ehcache manager will hang there.
public class CacheTest {
private static final Logger log = LoggerFactory.getLogger(CacheTest.class);
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(
AppConfig.class,CacheConfig.class);
ScenceRepository obj = context.getBean(ScenceRepository.class);
Scence user = obj.findOne(1);
System.out.println(user2.getName());
Scence user2 = obj.findOne(1);
System.out.println(user2.getName()); //shut down the Spring context.
((ConfigurableApplicationContext)context).close();
}
}
2.5 问题
启动报错:ERROR DiskStorageFactory:495 - Disk Write of 1 failed: java.io.NotSerializableException: com.huawei.traveller.domain.Scence ,Scence没有实现序列化,加上Serializable接口即可
参考
http://www.mkyong.com/spring/spring-caching-and-ehcache-example/
http://wangchaoqun.com/blog/2014/04/spring-cache-zhi-ehcache-he-memcached.html/
3、EhCache页面缓存
页面缓存,简单来说,就是把经常访问的页面(例如首页index.jsp)缓存起来,下次在访问的时候,直接从缓存读取(还要不要读取数据库?)
需要加载jar包:ehcache-web.jar、ehcache-core.jar
Spring EhCache页面缓存的做法,定义一个过滤器,这个过滤器规定了哪些文件需要被缓存;在规定的超时时间内,多次访问这个文件会从缓存中读取,而不是从数据库重新加载。
3.1 修改ehcache,增加一个名为SimplePageCachingFilter的cache项目
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
monitoring="autodetect">
<diskStore path="E:/cachetmpdir"/>
<defaultCache maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
maxElementsOnDisk="10000000" diskPersistent="false"
diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
<cache name="scenceCache" maxElementsInMemory="10000"
maxElementsOnDisk="1000" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU" />
<cache name="SimplePageCachingFilter" maxElementsInMemory="10000"
maxElementsOnDisk="1000" eternal="false" overflowToDisk="true"
diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LFU" />
</ehcache>
3.2 给应用配置一个过滤器
使用配置类的方法
FilterRegistration.Dynamic cacheFilterilterRegistration = servletContext.addFilter(
"webPageCacheFilter", net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter.class);
cacheFilterilterRegistration.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/index.*");
3.3 测试
如果连续刷新发现时间显示不变,说明页面缓存有效
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html >
<body>
<%=new java.util.Date()%>
</body>
</html>
3.4 问题
(1)本来页面缓存cache起名为WebPageCachingFilter,但是启动的时候报错:cache 'SimplePageCachingFilter' not found in configuration:看来一下源码,发现启动如果不起名的话,默认名为SimplePageCachingFilter,但是我又无法再类加载的时候起名,所以只能暂时用SimplePageCachingFilter
(2)页面缓存不生效问题:??
参考
http://www.iteye.com/topic/128458/
http://blog.csdn.net/zljjava/article/details/38422407
在Spring中使用cache(EhCache的对象缓存和页面缓存)的更多相关文章
- Spring中获取被代理的对象
目录 Spring中获取被代理的对象 获取Spring被代理对象什么时候可能会用到? Spring中获取被代理的对象 Spring中获取被代理的对象 ### 获取Spring被代理对象的JAVA工具类 ...
- cache在spring中使用
一:参考文章 (1)http://haohaoxuexi.iteye.com/blog/2123030 Spring使用Cache,这篇文章讲的比较详细. 注:本文是对参考文章和实际使用中经验的总结 ...
- spring使用ehcache实现页面缓存
ehcache缓存最后一篇,介绍页面缓存: 如果将应用的结构分为"page-filter-action-service-dao-db",那page层就是最接近用户的一层,一些特定的 ...
- spring中使用mockito
1 mockito介绍和入门 官方:https://github.com/mockito/mockito 入门: 5分钟了解Mockito http://liuzhijun.iteye.com/blo ...
- Linux内存中的Cache真的能被回收么?
在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个RHEL6的系统上,free命令的显示内容大概是这样一个状态: [root@tencent64 ~]# free ...
- Spring中ClassPathXmlApplicationContext类的简单使用
转自:http://www.cnblogs.com/shyy/archive/2011/09/29/2453057.html 一.简单的用ApplicationContext做测试的话,获得Sprin ...
- ASP.net中的Cache使用介绍
1.1.1 摘要(http://www.cnblogs.com/rush/archive/2012/06/30/2571438.html) 最近我们的系统面临着严峻性能瓶颈问题,这是由于访问量增加,客 ...
- Spring 中拦截器与过滤器的区别
spring 中拦截器 与servlet 的filter 有相似之处.比如二者都是aop 编程思想的体现都能实现权限检查,日志记录等. 不同之处 使用范围不同 Filter 是Servlet 规定的. ...
- Linux 内存中的Cache,真的能被回收么?
您真的了解Linux的free命令么? 在Linux系统中,我们经常用free命令来查看系统内存的使用状态.在一个RHEL6的系统上,free命令的显示内容大概是这样一个状态: 这里的默认显示单位是k ...
随机推荐
- SQL SERVER中架构的理解
在sqlserver 2005中,可能大家在工作或学习的时候会经常发现这样一些问题,你使用一个账户在数据库中创建了一张表,却发现你自己创建的表却没有修改和查询的权限,这是一件很郁闷的事情,在sqlse ...
- Learning Theory
Empiricial Risk Minimization 统计学习理论是整个机器学习到框架.试想我们学习的目的是什么呢?当然是为了具备用合理的方式处理问题的能力.统计学习理论要解决的问题就是基于数据找 ...
- 机器学习中的范数规则化之(一)L0、L1与L2范数 非常好,必看
机器学习中的范数规则化之(一)L0.L1与L2范数 zouxy09@qq.com http://blog.csdn.net/zouxy09 今天我们聊聊机器学习中出现的非常频繁的问题:过拟合与规则化. ...
- C#综合揭秘——Entity Framework 并发处理详解
引言 在软件开发过程中,并发控制是确保及时纠正由并发操作导致的错误的一种机制.从 ADO.NET 到 LINQ to SQL 再到如今的 ADO.NET Entity Framework,.NET 都 ...
- ASP.NET获取URL
//获取完整url (协议名+域名+站点名+文件名+参数) string fullUrl = Request.Url.ToString(); //获取客户端请求的URL信息(不包括主机和端口) str ...
- A Famous Music Composer
描述 Mr. B is a famous music composer. One of his most famous work was his set of preludes. These 24 p ...
- Android进阶笔记10:Android 万能适配器
1. Android 万能适配器 项目中Listview GridView几乎是必用的组件,Android也提供一套机制,为这些控件绑定数据,那就是Adapter.用起来虽然还不错,但每次都 ...
- Android(java)学习笔记112:局部位置的内部类的介绍
1.局部内部类 /* 局部内部类 A:可以直接访问外部类的成员 B:在局部位置,可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能 面试题: 局部内部类访问局部变量的注意事项? A:局部 ...
- ArcEngine中打开各种数据源(WorkSpace)的连接http://www.cnblogs.com/feilong3540717/archive/2011/08/07/2129906.html
ArcEngine中打开各种数据源(WorkSpace)的连接 ArcEngine中打开各种数据源(WorkSpace)的连接 (SDE.personal/File.ShapeFile.CAD数据.影 ...
- linux上传下载
linux传下载 1.可以通过xftp连接服务器直接 拖拽 2.yum install lrzsz 通过rz/sz命令上传下载