前言
Ehcache 是一个成熟的缓存框架,你可以直接使用它来管理你的缓存。
Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Ehcache),但本身不直接提供缓存功能的实现。它支持注解方式使用缓存,非常方便。
本文先通过Ehcache独立应用的范例来介绍它的基本使用方法,然后再介绍与Spring整合的方法。
概述
Ehcache是什么?
EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点。它是Hibernate中的默认缓存框架。
Ehcache已经发布了3.1版本。但是本文的讲解基于2.10.2版本。
为什么不使用最新版呢?因为Spring4还不能直接整合Ehcache 3.x。虽然可以通过JCache间接整合,Ehcache也支持JCache,但是个人觉得不是很方便。
安装
Ehcache
如果你的项目使用maven管理,添加以下依赖到你的pom.xml中。
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.10.2</version> <type>pom</type> </dependency>
如果你的项目不使用maven管理,请在 Ehcache官网下载地址 下载jar包。
Spring
如果你的项目使用maven管理,添加以下依赖到你的pom.xml中。
spring-context-support这个jar包中含有Spring对于缓存功能的抽象封装接口。
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.1.4.RELEASE</version> </dependency>
Ehcache的使用
HelloWorld范例
接触一种技术最快最直接的途径总是一个Hello World例子,毕竟动手实践印象更深刻,不是吗?
(1) 在classpath下添加ehcache.xml
添加一个名为helloworld的缓存。
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"> <!-- 磁盘缓存位置 --> <diskStore path="java.io.tmpdir/ehcache"/> <!-- 默认缓存 --> <defaultCache maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"/> <!-- helloworld缓存 --> <cache name="helloworld" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="5" timeToLiveSeconds="5" overflowToDisk="false" memoryStoreEvictionPolicy="LRU"/> </ehcache>
(2) EhcacheDemo.java
Ehcache会自动加载classpath根目录下名为ehcache.xml文件。
EhcacheDemo的工作步骤如下:
在EhcacheDemo中,我们引用ehcache.xml声明的名为helloworld的缓存来创建Cache对象;
然后我们用一个键值对来实例化Element对象;
将Element对象添加到Cache;
然后用Cache的get方法获取Element对象。
public class EhcacheDemo { public static void main(String[] args) throws Exception { // Create a cache manager final CacheManager cacheManager = new CacheManager(); // create the cache called "helloworld" final Cache cache = cacheManager.getCache("helloworld"); // create a key to map the data to final String key = "greeting"; // Create a data element final Element putGreeting = new Element(key, "Hello, World!"); // Put the element into the data store cache.put(putGreeting); // Retrieve the data element final Element getGreeting = cache.get(key); // Print the value System.out.println(getGreeting.getObjectValue()); } }
输出
Hello, World!
Ehcache基本操作
Element、Cache、CacheManager是Ehcache最重要的API。
创建CacheManager
下面的代码列举了创建CacheManager的五种方式。
使用静态方法create()会以默认配置来创建单例的CacheManager实例。
newInstance()方法是一个工厂方法,以默认配置创建一个新的CacheManager实例。
此外,newInstance()还有几个重载函数,分别可以通过传入String、URL、InputStream参数来加载配置文件,然后创建CacheManager实例。
// 使用Ehcache默认配置获取单例的CacheManager实例 CacheManager.create(); String[] cacheNames = CacheManager.getInstance().getCacheNames(); // 使用Ehcache默认配置新建一个CacheManager实例 CacheManager.newInstance(); String[] cacheNames = manager.getCacheNames(); // 使用不同的配置文件分别创建一个CacheManager实例 CacheManager manager1 = CacheManager.newInstance("src/config/ehcache1.xml"); CacheManager manager2 = CacheManager.newInstance("src/config/ehcache2.xml"); String[] cacheNamesForManager1 = manager1.getCacheNames(); String[] cacheNamesForManager2 = manager2.getCacheNames(); // 基于classpath下的配置文件创建CacheManager实例 URL url = getClass().getResource("/anotherconfigurationname.xml"); CacheManager manager = CacheManager.newInstance(url); // 基于文件流得到配置文件,并创建CacheManager实例 InputStream fis = new FileInputStream(new File ("src/config/ehcache.xml").getAbsolutePath()); try { CacheManager manager = CacheManager.newInstance(fis); } finally { fis.close(); }
添加缓存
需要强调一点,Cache对象在用addCache方法添加到CacheManager之前,是无效的。
使用CacheManager的addCache方法可以根据缓存名将ehcache.xml中声明的cache添加到容器中;它也可以直接将Cache对象添加到缓存容器中。
Cache有多个构造函数,提供了不同方式去加载缓存的配置参数。
有时候,你可能需要使用API来动态的添加缓存,下面的例子就提供了这样的范例。
// 除了可以使用xml文件中配置的缓存,你也可以使用API动态增删缓存 // 添加缓存 manager.addCache(cacheName); // 使用默认配置添加缓存 CacheManager singletonManager = CacheManager.create(); singletonManager.addCache("testCache"); Cache test = singletonManager.getCache("testCache"); // 使用自定义配置添加缓存,注意缓存未添加进CacheManager之前并不可用 CacheManager singletonManager = CacheManager.create(); Cache memoryOnlyCache = new Cache("testCache", 5000, false, false, 5, 2); singletonManager.addCache(memoryOnlyCache); Cache test = singletonManager.getCache("testCache"); // 使用特定的配置添加缓存 CacheManager manager = CacheManager.create(); Cache testCache = new Cache( new CacheConfiguration("testCache", maxEntriesLocalHeap) .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU) .eternal(false) .timeToLiveSeconds(60) .timeToIdleSeconds(30) .diskExpiryThreadIntervalSeconds(0) .persistence(new PersistenceConfiguration().strategy(Strategy.LOCALTEMPSWAP))); manager.addCache(testCache);
删除缓存
删除缓存比较简单,你只需要将指定的缓存名传入removeCache方法即可。
CacheManager singletonManager = CacheManager.create(); singletonManager.removeCache("sampleCache1");
实现基本缓存操作
Cache最重要的两个方法就是put和get,分别用来添加Element和获取Element。
Cache还提供了一系列的get、set方法来设置或获取缓存参数,这里不一一列举,更多API操作可参考官方API开发手册。
/** * 测试:使用默认配置或使用指定配置来创建CacheManager * * @author victor zhang */ public class CacheOperationTest { private final Logger log = LoggerFactory.getLogger(CacheOperationTest.class); /** * 使用Ehcache默认配置(classpath下的ehcache.xml)获取单例的CacheManager实例 */ @Test public void operation() { CacheManager manager = CacheManager.newInstance("src/test/resources/ehcache/ehcache.xml"); // 获得Cache的引用 Cache cache = manager.getCache("userCache"); // 将一个Element添加到Cache cache.put(new Element("key1", "value1")); // 获取Element,Element类支持序列化,所以下面两种方法都可以用 Element element1 = cache.get("key1"); // 获取非序列化的值 log.debug("key:{}, value:{}", element1.getObjectKey(), element1.getObjectValue()); // 获取序列化的值 log.debug("key:{}, value:{}", element1.getKey(), element1.getValue()); // 更新Cache中的Element cache.put(new Element("key1", "value2")); Element element2 = cache.get("key1"); log.debug("key:{}, value:{}", element2.getObjectKey(), element2.getObjectValue()); // 获取Cache的元素数 log.debug("cache size:{}", cache.getSize()); // 获取MemoryStore的元素数 log.debug("MemoryStoreSize:{}", cache.getMemoryStoreSize()); // 获取DiskStore的元素数 log.debug("DiskStoreSize:{}", cache.getDiskStoreSize()); // 移除Element cache.remove("key1"); log.debug("cache size:{}", cache.getSize()); // 关闭当前CacheManager对象 manager.shutdown(); // 关闭CacheManager单例实例 CacheManager.getInstance().shutdown(); } }
缓存配置
Ehcache支持通过xml文件和API两种方式进行配置。
xml方式
Ehcache的CacheManager构造函数或工厂方法被调用时,会默认加载classpath下名为ehcache.xml的配置文件。如果加载失败,会加载Ehcache jar包中的ehcache-failsafe.xml文件,这个文件中含有简单的默认配置。
ehcache.xml配置参数说明:
ehcache.xml的一个范例
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"> <!-- 磁盘缓存位置 --> <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> <cache name="userCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="3" timeToLiveSeconds="3" maxEntriesLocalDisk="10000000" overflowToDisk="false" memoryStoreEvictionPolicy="LRU"/> </ehcache>
API方式
xml配置的参数也可以直接通过编程方式来动态的进行配置(dynamicConfig没有设为false)。
Cache cache = manager.getCache("sampleCache"); CacheConfiguration config = cache.getCacheConfiguration(); config.setTimeToIdleSeconds(60); config.setTimeToLiveSeconds(120); config.setmaxEntriesLocalHeap(10000); config.setmaxEntriesLocalDisk(1000000);
也可以通过disableDynamicFeatures()方式关闭动态配置开关。配置以后你将无法再以编程方式配置参数。
Cache cache = manager.getCache("sampleCache"); cache.disableDynamicFeatures();
Spring整合Ehcache
Spring3.1开始添加了对缓存的支持。和事务功能的支持方式类似,缓存抽象允许底层使用不同的缓存解决方案来进行整合。
Spring4.1开始支持JSR-107注解。
注:我本人使用的Spring版本为4.1.4.RELEASE,目前Spring版本仅支持Ehcache2.5以上版本,但不支持Ehcache3。
绑定Ehcache
org.springframework.cache.ehcache.EhCacheManagerFactoryBean这个类的作用是加载Ehcache配置文件。
org.springframework.cache.ehcache.EhCacheCacheManager这个类的作用是支持net.sf.ehcache.CacheManager。
spring-ehcache.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.2.xsd"> <description>ehcache缓存配置管理文件</description> <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:ehcache/ehcache.xml"/> </bean> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="ehcache"/> </bean> <!-- 启用缓存注解开关 --> <cache:annotation-driven cache-manager="cacheManager"/> </beans>
使用Spring的缓存注解
开启注解
Spring为缓存功能提供了注解功能,但是你必须启动注解。
你有两个选择:
(1) 在xml中声明
像上一节spring-ehcache.xml中的做法一样,使用<cache:annotation-driven/>
<cache:annotation-driven cache-manager="cacheManager"/>
(2) 使用标记注解
你也可以通过对一个类进行注解修饰的方式在这个类中使用缓存注解。
范例如下:
@Configuration @EnableCaching public class AppConfig { }
注解基本使用方法
Spring对缓存的支持类似于对事务的支持。
首先使用注解标记方法,相当于定义了切点,然后使用Aop技术在这个方法的调用前、调用后获取方法的入参和返回值,进而实现了缓存的逻辑。
下面三个注解都是方法级别:
@Cacheable
表明所修饰的方法是可以缓存的:当第一次调用这个方法时,它的结果会被缓存下来,在缓存的有效时间内,以后访问这个方法都直接返回缓存结果,不再执行方法中的代码段。
这个注解可以用condition属性来设置条件,如果不满足条件,就不使用缓存能力,直接执行方法。
可以使用key属性来指定key的生成规则。
@CachePut
与@Cacheable不同,@CachePut不仅会缓存方法的结果,还会执行方法的代码段。
它支持的属性和用法都与@Cacheable一致。
@CacheEvict
与@Cacheable功能相反,@CacheEvict表明所修饰的方法是用来删除失效或无用的缓存数据。
下面是@Cacheable、@CacheEvict和@CachePut基本使用方法的一个集中展示:
@Service public class UserService { // @Cacheable可以设置多个缓存,形式如:@Cacheable({"books", "isbns"}) @Cacheable({"users"}) public User findUser(User user) { return findUserInDB(user.getId()); } @Cacheable(value = "users", condition = "#user.getId() <= 2") public User findUserInLimit(User user) { return findUserInDB(user.getId()); } @CachePut(value = "users", key = "#user.getId()") public void updateUser(User user) { updateUserInDB(user); } @CacheEvict(value = "users") public void removeUser(User user) { removeUserInDB(user.getId()); } @CacheEvict(value = "users", allEntries = true) public void clear() { removeAllInDB(); } }
@Caching
如果需要使用同一个缓存注解(@Cacheable、@CacheEvict或@CachePut)多次修饰一个方法,就需要用到@Caching。
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") }) public Book importBooks(String deposit, Date date)
@CacheConfig
与前面的缓存注解不同,这是一个类级别的注解。
如果类的所有操作都是缓存操作,你可以使用@CacheConfig来指定类,省去一些配置。
@CacheConfig("books") public class BookRepositoryImpl implements BookRepository { @Cacheable public Book findBook(ISBN isbn) {...} }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍SpringBoot2 整合Ehcache组件,轻量级缓存管理的原理解析,包括了SpringBoot2 整合Ehcache组件,轻量级缓存管理的原理解析的使用技巧和注意事项,需要的朋友参考一下 本文源码:GitHub·点这里 || GitEE·点这里 一、Ehcache缓存简介 1、基础简介 EhCache是一个纯Java的进程内缓存框架,具有快速、上手简单等特点,是Hibernat
本文向大家介绍详解Spring+Hiernate整合,包括了详解Spring+Hiernate整合的使用技巧和注意事项,需要的朋友参考一下 一、整合目标 1.由IoC容器管理Hibernate的SessionFactory 2.让Hibernate使用Spring的声明式事务 二、整合步骤 先加入Hibernat,再加入Spring,再进行整合。 第一步: 配置Hibernate 1.加入Hibe
本文向大家介绍详解spring整合shiro权限管理与数据库设计,包括了详解spring整合shiro权限管理与数据库设计的使用技巧和注意事项,需要的朋友参考一下 之前的文章中我们完成了基础框架的搭建,现在基本上所有的后台系统都逃不过权限管理这一块,这算是一个刚需了。现在我们来集成shiro来达到颗粒化权限管理,也就是从连接菜单到页面功能按钮,都进行权限都验证,从前端按钮的显示隐藏,到后台具体功能
本文向大家介绍详解spring+springmvc+mybatis整合注解,包括了详解spring+springmvc+mybatis整合注解的使用技巧和注意事项,需要的朋友参考一下 每天记录一点点,慢慢的成长,今天我们学习了ssm,这是我自己总结的笔记,大神勿喷!谢谢,主要代码!! ! spring&springmvc&mybatis整合(注解) 1.jar包 2.引入web.xml文件 3.创
我使用ehcache-spring注释来缓存我的应用程序数据。为此,我有以下配置: 我想获取“net”的参考。旧金山。ehcache。CacheManager“超出配置的bean”ehCacheManager“。因此,我可以使用“CacheManager”直接在缓存中手动执行put或remove操作。 任何获取“net”引用的方法。旧金山。ehcache。CacheManager“出”组织。spr
本文向大家介绍spring整合struts2过程详解,包括了spring整合struts2过程详解的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了spring整合struts2过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 首先将以下jar包加入到lib文件夹中: 基础目录: Person.java PersonService