以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配置启用注解驱动的缓存

[java] view plain copy

print?

  1. package com.snieri.authentication.ehcache;
  2. import org.springframework.cache.CacheManager;
  3. import org.springframework.cache.annotation.EnableCaching;
  4. import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
  5. import org.springframework.context.annotation.Configuration;
  6. @Configuration
  7. @EnableCaching//启用缓存
  8. public class CachingConfig {
  9. /**
  10. * 声明缓存管理器
  11. */
  12. public CacheManager cacheManager() {
  13. return new ConcurrentMapCacheManager();
  14. }
  15. }
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;@[email protected]//启用缓存public class CachingConfig {    /**     * 声明缓存管理器     */    public CacheManager cacheManager() {        return new ConcurrentMapCacheManager();    }    }

程序清单2:XML配置启用注解驱动缓存

[html] view plain copy

print?

  1. <cache:annotation-driven/>
  2. 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

[java] view plain copy

print?

  1. package com.snieri.authentication.ehcache;
  2. import org.springframework.cache.annotation.EnableCaching;
  3. import org.springframework.cache.ehcache.EhCacheCacheManager;
  4. import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.core.io.ClassPathResource;
  8. import net.sf.ehcache.CacheManager;
  9. @Configuration
  10. @EnableCaching//启用缓存
  11. public class CachingConfig {
  12. /**
  13. * @param cacheManager 是 net.sf.ehcache.CacheManager的一个实例
  14. * 配置EhCacheCacheManager缓存管理器
  15. */
  16. @Bean
  17. public EhCacheCacheManager cacheManager(CacheManager cacheManager) {
  18. return new EhCacheCacheManager(cacheManager);
  19. }
  20. @Bean
  21. public EhCacheManagerFactoryBean ehcache() {
  22. EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
  23. ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("**/**/ehcache.xml"));
  24. return ehCacheManagerFactoryBean;
  25. }
  26. }
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;@[email protected]//启用缓存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

[html] view plain copy

print?

  1. <!-- 启用缓存 -->
  2. <cache:annotation-driven cache-manager ="cacheManager" />
  3. <!--声明一个缓存管理器(EhCacheCacheManager) 这里的实现代码是通过传入EhCache的CacheManager实例实现的 -->
  4. <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache"/>
  5. <!--这里并不是EhCacheManagerFactoryBean的实例,而是EhCache中CacheManager的一个实例  -->
  6. <!--因为Spring和EhCache都定义了CacheManager类型  -->
  7. <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
  8. <property name="configLocation" value="classpath:/ehcache.xml" />
  9. <property name="shared" value="true"/>
  10. </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整合使用多个缓存管理器

原文地址:https://www.cnblogs.com/jpfss/p/8336712.html

时间: 2024-10-27 06:09:35

以Spring整合EhCache为例从根本上了解Spring缓存这件事(转)的相关文章

Spring整合Ehcache管理缓存

Ehcache 是一个成熟的缓存框架,你可以直接使用它来管理你的缓存. Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Ehcache),但本身不直接提供缓存功能的实现.它支持注解方式使用缓存,非常方便.本文先通过Ehcache独立应用的范例来介绍它的基本使用方法,然后再介绍与Spring整合的方法. 概述 Ehcache是什么?EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点.它是Hibernate中的默认缓存框架.Ehcache已经发布了3.1版本

beetl-spring Beetl的Spring整合扩展(2):Beetl与Spring MVC整合

二.Beetl与Spring MVC整合 本章主要介绍通过beetl-spring完成Beetl与Spring MVC整合的功能.和Beetl自带的BeetlSpringViewResolver及BeetlSpringView相比,本项目提供的BeetlViewResolver增强了视图解析器的功能,使多视图解析器各自使用各自的GroupTemplate以使用不同的Beetl配置成为可能. 2.1 BeetlViewResolver BeetlViewResolver是一个Spring MVC视

Spring AOP +EHcache为Service层方法增加缓存

在铁科院做了一个关于医保报销的项目,在这个个系统中大量使用了下拉列表框,系统主要是给机关单位使用而且都是一些干部退休了啥的,年龄都比较大不愿意自己输入东西,因此界面上的很多值都是下拉列表框从数据字典表里面加载出来. 如此以来字典表的数据量变的越来越大,在一个界面上往往需要频繁的与字典表交互,觉的很影响性能于是我们增加了缓存,即为service层中的指定方法缓存功能,具体实现是利用Spring AOP+EHcache来做. 第一次执行某个方法的时候会去数据库里面查询,当第二次执行该方法时就会去从缓

spring整合ehcache 注解实现查询缓存,并实现实时缓存更新或删除

写在前面:上一篇博客写了spring cache和ehcache的基本介绍,个人建议先把这些最基本的知识了解了才能对今天主题有所感触.不多说了,开干! 注:引入jar <!-- 引入ehcache缓存 --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.8.3</version&g

spring学习笔记(26)——spring整合ehcache

ehcache配置文件 spring配置文件中配置 使用 ehcache配置文件 在src下创建ehcache.xml <?xml version="1.0" encoding="UTF-8"?> <ehcache name="es"> <diskStore path="java.io.tmpdir"/> <!-- name属性是根据需要自行取名 --> <!-- cach

spring+shiro+ehcache整合

1.导入jar包(pom.xml文件) <!-- ehcache缓存框架 --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>2.6.11</version> </dependency> Spring 整合 ehcache 包 spring-context-

struts2与spring整合时需要注意的点

首先我们需要明白spring整合struts2中的什么东西,spring中的核心就是IOC和AOP,IOC是对象的容器,AOP是处理动态代理的;比如spring与hibernate整合时就要用到aop,具体就是把事务的开启与关闭交于spring中的aop处理.一句话,spring就是整合struts2的对象. 先前struts.xml配置文件中action标签中的class属性的值是"包名+类名",这样配置就可以让struts2自己生成对象,但这样不符合模式设计六大原则,为了解决这个问

使用Spring提供的缓存抽象机制整合EHCache为项目提供二级缓存

Spring自身并没有实现缓存解决方案,但是对缓存管理功能提供了声明式的支持,能够与多种流行的缓存实现进行集成. Spring Cache是作用在方法上的(不能理解为只注解在方法上),其核心思想是:当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值存放在缓存中,等到下次利用同样的参数调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回.所以在使用Spring Cache的时候我们要保证我们的缓存的方法对于相同的方法参数要有相同的返回结果. 1.适合和不适合保存到二级缓存的数

【Struts2】Struts2与Spring整合后,如何指定Action为多例模式

Strust2默认是多例的,但是Spring默认是单例的,在进行Spring+Strust2整合的时候,就需要把Spring管理的action指定为多例模式,只需要在action上面加上@Scope("prototype") 例如: //... @Scope("prototype") public class UserAction { //... public String execute(){ //... }} //...