以Spring整合EhCache为例从根本上了解Spring缓存这件事(转)
前两节“Spring缓存抽象”和“基于注解驱动的缓存”是为了更加清晰的了解Spring缓存机制,整合任何一个缓存实现或者叫缓存供应商都应该了解并清楚前两节,如果只是为了快速的应用EhCache到Spring项目中,请直接前往第三节“Spring整合EhCache缓存”。
一、 Spring缓存抽象
1. 注意和核心思想
Spring自身并没有实现缓存解决方案,但是对缓存管理功能提供了声明式的支持,能够与多种流行的缓存实现进行集成。
Spring Cache是作用在方法上的(不能理解为只注解在方法上),其核心思想是:当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值存放在缓存中,等到下次利用同样的参数调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回。所以在使用Spring Cache的时候我们要保证我们的缓存的方法对于相同的方法参数要有相同的返回结果。
2. Spring对Cache的支持有两种方式
- 基于注解驱动的缓存
- 基于XML配置声明的缓存
下来我们介绍基于注解驱动的缓存
二、 基于注解驱动的缓存
在往bean上添加缓存注解之前,必须要启动Spring对注解驱动缓存的支持
1. 启用Spring对注解驱动缓存的支持
启用Spring对注解驱动缓存的支持,也是有两种方式的:
- Java配置(这个方法可以比较清晰的了解缓存管理器是如何声明的)
- XML配置(这个方法比较方便简单,这里的XML配置不能跟上面的“基于XML配置声明的缓存”搞混,两者不是同一层概念)
下面用一个简单的例子来说明这两种方法的区别,这跟Spring整合EhCache没什么关系,但是可以让大家搞懂缓存管理器,也就是我们下节要说的。
程序清单1: Java配置启用注解驱动的缓存
- package com.snieri.authentication.ehcache;
- import org.springframework.cache.CacheManager;
- import org.springframework.cache.annotation.EnableCaching;
- import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
- import org.springframework.context.annotation.Configuration;
- @Configuration
- @EnableCaching//启用缓存
- public class CachingConfig {
- /**
- * 声明缓存管理器
- */
- public CacheManager cacheManager() {
- return new ConcurrentMapCacheManager();
- }
- }
package com.snieri.authentication.ehcache; import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Configuration; @Configuration
@EnableCaching//启用缓存
public class CachingConfig {
/**
* 声明缓存管理器
*/
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
} }
程序清单2:XML配置启用注解驱动缓存
- <cache:annotation-driven/>
- n id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager"></bean>
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager"></bean>
这两种方式,Java配置方式是通过使用@EnableCaching启用注解驱动的缓存,XML配置方式是通过使用<cache:annotation-driven/>启用注解驱动的缓存。本质上来讲,这两种工作方式是相同的,它们都会创建一个切面(AOP)并出发Spring缓存注解的切点(pointcut)。
在这两个程序清单中,不仅仅启用了注解驱动的缓存,还声明了一个缓存管理器(cache manager)的bean。缓存管理器是Spring抽象的核心,它能够与多个流行的缓存实现进行集成。这里又提到这句话,请大家切记。
上面的例子声明了一个ConcurrentMapCacheManager,这个简单的缓存管理器使用java.util.concurrent.ConcurrentHashMap作为其缓存存储。这个缓存非常简单,对于开发、测试或其他基础的应用来讲,是一个不错的选择。但是它的缓存存储是基于内存的,所以它的声明周期是与应用关联的,对于生产级别的大型企业级应用程序,这个缓存并不理想。
幸好,Spring有多个缓存管理器方案可供选择,请看下节。
2. 缓存管理器(这里的概念搞清楚很重要)
Spring内置很多缓存管理器(从Spring3到Spring4好像有7个吧,记不太清了,有兴趣的可以查查)
SimpleCacheManager
NoOpCacheManager
ConcurrentMapCacheManager(这个缓存管理器就是上面的例子介绍的)
CompositeCacheManager
EhCacheCacheManager(看到这里终于见到标题主人翁了)
RedisCacheManager(来自Spring Date Redis项目)
GemfireCacheManager(来自Spring Date GemFire项目)
可以看到,在为Spring的缓存抽象选择缓存管理器时,我们有很多可选方案。具体选择哪一个要取决于想要使用的底层缓存供应商。每一个方案都可以为应用提供不同风格的缓存,其中有一些会比其他的更加适用于生产环境。尽管所做出的选择会影响到数据如何缓存,但是Spring声明缓存的方式并没有什么差别。也就是说,无论你用什么缓存管理器,Spring声明缓存的方式是不变的,注解驱动缓存(java配置启动、XML配置启动)和XML配置缓存两种方式。
三、 Spring整合EhCache缓存
在往bean上添加缓存注解之前,必须要启动Spring对注解驱动缓存的支持,所以说有两个步骤:
启用Spring对注解驱动缓存的支持
声明某些方法或者整个类使用缓存,这一步包含编写ehcache.xml文件(后面会有详细介绍)
1. 启用Spring对注解驱动缓存的支持
这里依然介绍的是基于注解驱动,上面已经讲了,有两个启动方式:Java配置的方式和XML配置的方式(两种方式本质是一样的)。XML是我们常见的启动方式。
程序清单3:以Java配置的方式设置EhCacheManager
- package com.snieri.authentication.ehcache;
- import org.springframework.cache.annotation.EnableCaching;
- import org.springframework.cache.ehcache.EhCacheCacheManager;
- import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.core.io.ClassPathResource;
- import net.sf.ehcache.CacheManager;
- @Configuration
- @EnableCaching//启用缓存
- public class CachingConfig {
- /**
- * @param cacheManager 是 net.sf.ehcache.CacheManager的一个实例
- * 配置EhCacheCacheManager缓存管理器
- */
- @Bean
- public EhCacheCacheManager cacheManager(CacheManager cacheManager) {
- return new EhCacheCacheManager(cacheManager);
- }
- @Bean
- public EhCacheManagerFactoryBean ehcache() {
- EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
- ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("**/**/ehcache.xml"));
- return ehCacheManagerFactoryBean;
- }
- }
package com.snieri.authentication.ehcache; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource; import net.sf.ehcache.CacheManager; @Configuration
@EnableCaching//启用缓存
public class CachingConfig {/**
* @param cacheManager 是 net.sf.ehcache.CacheManager的一个实例
* 配置EhCacheCacheManager缓存管理器
*/
@Bean
public EhCacheCacheManager cacheManager(CacheManager cacheManager) {
return new EhCacheCacheManager(cacheManager);
} @Bean
public EhCacheManagerFactoryBean ehcache() { EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("**/**/ehcache.xml"));
return ehCacheManagerFactoryBean; }
}
程序清单4:以XML配置的方式设置EhCacheManager
- <!-- 启用缓存 -->
- <cache:annotation-driven cache-manager ="cacheManager" />
- <!--声明一个缓存管理器(EhCacheCacheManager) 这里的实现代码是通过传入EhCache的CacheManager实例实现的 -->
- <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache"/>
- <!--这里并不是EhCacheManagerFactoryBean的实例,而是EhCache中CacheManager的一个实例 -->
- <!--因为Spring和EhCache都定义了CacheManager类型 -->
- <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
- <property name="configLocation" value="classpath:/ehcache.xml" />
- <property name="shared" value="true"/>
- </bean>
<!-- 启用缓存 -->
<cache:annotation-driven cache-manager ="cacheManager" />
<!--声明一个缓存管理器(EhCacheCacheManager) 这里的实现代码是通过传入EhCache的CacheManager实例实现的 -->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache"/>
<!--这里并不是EhCacheManagerFactoryBean的实例,而是EhCache中CacheManager的一个实例 -->
<!--因为Spring和EhCache都定义了CacheManager类型 -->
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:/ehcache.xml" />
<property name="shared" value="true"/>
</bean>
在程序清单3中,cacheManager()方法创建了一个EhCacheCacheManager实例,这是通过传入EhCache的cacheManager实例实现的。这里比较诡异,让人感到迷惑,而且在导包的时候往往会容易导错,这是因为Spring和EhCache都定义了CacheManager类型。需要明确的是,EhCache的CacheManager要被注入到Spring的EhCacheCacheManager之中。
可以从import的包中也可以查看到这些信息(这也算是马后炮了,但是有助于我们理解)。下面这段比较重要,认真思考。
*我们需要使用EhCache的CacheManager来进行注入,所以必须声明一个CacheManager bean。为了对其进行简化,Spring提供了EhCacheManagerFactoryBean来生成EhCache的CacheManager。方法ehcache()会创建并返回一个EhCacheManagerFactoryBean实例。因为它是一个工厂bean(也就是说,它实现了Spring的FactoryBean接口),所以注册在Spring应用上下文的并不是EhCacheManagerFactoryBean的实例,而是EhCache的CacheManager实例,因此适合注入到EhCacheCacheManager之中。
2. 声明某些方法或整个类哪个使用缓存并且编写ehcache.xml文件
下面两个内容可以在我转载的另一个博文《Spring使用Cache》中查看,比较清晰,结合起来的话应该会对spring缓存有所了解。
1) 为方法或类添加注解以支持缓存
2) ehcache.xml配置
而以下的这两节我会在不久进行整理,注意查看我的博文。
四、 Spring整合Redis缓存
五、 Spring整合使用多个缓存管理器
以Spring整合EhCache为例从根本上了解Spring缓存这件事(转)的更多相关文章
- Spring整合Ehcache管理缓存
前言 Ehcache 是一个成熟的缓存框架,你可以直接使用它来管理你的缓存. Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Ehcache),但本身不直接提供缓存功能的实现.它 ...
- Spring整合Ehcache管理缓存(转)
目录 前言 概述 安装 Ehcache的使用 HelloWorld范例 Ehcache基本操作 创建CacheManager 添加缓存 删除缓存 实现基本缓存操作 缓存配置 xml方式 API方式 S ...
- Spring整合EHCache框架
在Spring中使用缓存可以有效地避免不断地获取相同数据,重复地访问数据库,导致程序性能恶化. 在Spring中已经定义了缓存的CacheManager和Cache接口,只需要实例化便可使用. Spr ...
- Spring整合EhCache详解
一.EhCache介绍 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider.Ehcache是一种广泛使用的开 源Java分布 ...
- spring整合ehcache实现缓存
Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Ehcache),但本身不直接提供缓存功能的实现.它支持注解方式使用缓存,非常方便. spring本身内置了对Cache的支持,之 ...
- spring整合ehcache注解实现查询缓存,并实现实时缓存更新或删除
转载: http://www.importnew.com/23358.html 写在前面:上一篇博客写了spring cache和ehcache的基本介绍,个人建议先把这些最基本的知识了解了才能对今天 ...
- spring整合ehcache 注解实现查询缓存,并实现实时缓存更新或删除
写在前面:上一篇博客写了spring cache和ehcache的基本介绍,个人建议先把这些最基本的知识了解了才能对今天主题有所感触.不多说了,开干! 注:引入jar <!-- 引入ehcach ...
- 2.spring整合ehcache 注解实现查询缓存,并实现实时缓存更新或删除
转自:http://www.importnew.com/23358.html 写在前面:上一篇博客写了spring cache和ehcache的基本介绍,个人建议先把这些最基本的知识了解了才能对今天主 ...
- spring+shiro+ehcache整合
1.导入jar包(pom.xml文件) <!-- ehcache缓存框架 --> <dependency> <groupId>net.sf.ehcache</ ...
随机推荐
- [BZOJ3566][SHOI2014]概率充电器 换根树形DP
链接 题意:n个充电元件形成一棵树,每个点和每条边都有各自的充电概率,元件可以自身充电或者通过其他点和边间接充电,求充电状态元件的期望个数 题解 设1为根节点 设 \(f[x]\) 表示 \(x\) ...
- 扩展: 简介pyinstaller: py文件压缩成exe文件
写在开始: 后缀 .py 的文件, 必须在装有python解释器, 和相对应的模块下才能运行. 对于装13来说,比较不方便. 如果人家电脑上也装上了python解释器, 说不好一眼就看穿了 自己写的 ...
- System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接
System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接
- java判断编码格式
package com.sssjd.storm; import java.io.UnsupportedEncodingException; /** * Created by jorda on 2017 ...
- 【Python】【Head First Python】【chapter1】2 - sys.stdout 和 print 的区别
sys.stdout 和 print 的区别 首先,通过 help(print) 得到print内建函数的参数 Help on built-in function print in module bu ...
- 【OC学习-8】存取器方法?getter和setter?事实上就是赋值和返回值的两种函数
我们在声明类的时候,有实例变量+方法(函数),这些实例变量假设默认的话都是protected类型,一般无法直接訪问.更别提赋值和调用了,所以就产生了两种函数,getter函数就是可以返回实例变量的值, ...
- hdu 1003 Max Sum 最大字段和 dp
今天看了一上午dp.看不太懂啊.dp确实不简单.今天開始学习dp,搜了杭电的dp46道,慢慢来吧.白书上的写的 又不太具体,先写几道题目再说. .. 题目连接:id=516&page=1&qu ...
- WebService三大基本元素 SOAP WSDL UDDI
转自:https://blog.csdn.net/hhooong/article/details/51763128 1.SOAP 即 Simple Object AccessProtocol 也就是简 ...
- 19,tuple多元数组
#include <iostream> #include <tuple> using namespace std; void main() { char ch = 'a'; ; ...
- Android 多线程断点续传同时下载多个大文件
最近学习在Android环境中一些网络请求方面的知识,其中有一部分是关于网络下载方面的知识.在这里解析一下自己写的demo,总结一下自己所学的知识.下图为demo的效果图,仿照一些应用下载商城在Lis ...