`

spring + EHCache 注解方式配置缓存

 
阅读更多

最原始的进行缓存的方式:

最原始的使用缓存的方式是通过一个全局map保存获取过的数据,下次获取数据时先从map中提取,如果有就直接返回,如果没有就从数据库中去读取,然后放入map中,当然,在做更新操作时需要同步更新这个map中的数据。这种方式虽然原始,但是在一些简单的场景下已经够用了,比如Java的类加载器就是使用的这种方式缓存加载过的class。
 
 
通过ehcache以编程方式使用缓存:
跟上面的方式相同,但是缓存通过ehcache去管理,当然比使用map有N多种好处,比如缓存太大了快达到上限之后,将哪一部分缓存清除出去。这种方式完全是通过代码的方式使用ehcache缓存,虽然自由,却也很麻烦;有些比如单纯的场景下,不需要如此麻烦,直接通过注解就行了。
以前在Spring项目中要通过注解的方式使用缓存,比如借助一个jar包:ehcache-spring-annotations.jar,可以在googlecode上面下载,不过已经很久没有更新过了。
 
 
使用ehcache-spring-annotations.jar

Spring配置文件:
<?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:ehcache= "http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
      xsi:schemaLocation= "
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd">
 
      <ehcache:annotation-driven cache-manager ="ehcacheManager" />
      <ehcache:config cache-manager = "ehcacheManager">
           <ehcache:evict-expired-elements
               interval= "60" />
      </ehcache:config >
      <bean id = "ehcacheManager"
           class= "org.springframework.cache.ehcache.EhCacheManagerFactoryBean" >
           <property name = "configLocation" value= "classpath:ehcache.xml" />
      </bean >
</beans>

共有两个注解:
  • @Cacheabele      :指定方法使用缓存
  • @TriggersRemove  :从缓存中移除对象
在查询的方法上使用缓存
@Cacheable(cacheName="platform.config")
 
在删除或更新的方法上清空缓存:
@TriggersRemove(cacheName="platform.config", when=When.AFTER_METHOD_INVOCATION , removeAll=true)
public void updateConfig(SystemConfig config) {
     this.configDao.update(config);
}
 
下面是一个实际例子:
在互联网应用中,由于并发量比传统的企业级应用会高出很多,所以处理大并发的问题就显得尤为重要。在硬件资源一定的情况下,在软件层面上解决高并发问题会比较经济实惠一些。解决并发的根本在于提高系统的响应时间与单位时间的吞吐量。解决问题的思路可分两个维度,一是提高系统的单位时间内的运算效率(比如集群),二是减少系统不必要的开支(比如缓存)。缓存又会分为客户端缓存与服务器端缓存,本文就javaEE项目的服务器端缓存方案展开介绍。
根据网上资料Java缓存解决方案有多种,用的比较多,中文资料也比较多的有:oscache、ehcache。如何选择参考了网上前辈们的评价。如下:
http://blog.sina.com.cn/s/blog_46d5caa40100ka9z.html
由于我们系统采用springMVC,所以在选定ehcache后,就着重研究ehcache与SpringMVC的整合,注解当然是要用到的。参考资料:
http://hanqunfeng.iteye.com/blog/603719
在了解了spring与ehcache整合之后发现这东西是不是很简单,但是笔者在查找资料的时候又发现了更简单解决方案,google为spring与ehcache整合提供了封装包,参考资料如下:
http://luck332.iteye.com/blog/1001783
http://code.google.com/p/ehcache-spring-annotations/
http://blog.goyello.com/2010/07/29/quick-start-with-ehcache-annotations-for-spring/(推荐参考,虽然是e文的,但是基本可以看懂)
方案

         进入正题。
SpringMVC + ehcache(google  ehcache-spring-annotations),基于注解解决服务器端数据缓存。
1.      下载所需jar包

1.         Ehcache的jar:
ehcache-2.7.1.jar
slf4j-api-1.6.6.jar
slf4j-jdk14-1.6.6.jar
down下来之后lib里面会有以上三个包(这两个slf4j的包一般项目里会有,换成最新的版本即可),下载地址如下:
http://ehcache.org/downloads/destination?name=ehcache-2.7.2-distribution.tar.gz&bucket=tcdistributions&file=ehcache-2.7.2-distribution.tar.gz
 
2.         ehcache-spring-annotations 的jar:
ehcache-spring-annotations-1.2.0.jar
ehcache-spring-annotations-1.2.0-sources.jar
down下来之后,从文件夹取以上2个包,其他的包忽视。下载地址:
http://code.google.com/p/ehcache-spring-annotations/downloads/detail?name=ehcache-spring-annotations-1.2.0-nodep.tar.gz
当然google也提供了开发版的包,里面提供了源码。jar还支持二维码下载,下载到手机上?不知道google咋想的。。。
2.      配置

   1.   ehcacheApplication.xml,该文件里面配置基本不变,需要将该文件加入web.xml
 
Xml代码  收藏代码
<?xml version="1.0" encoding="UTF-8"?>    
<!--   
/**  
 *   
 * 缓存配置  
 * @author zyz   
 * @date 2013年7月2日  
 *   
 */ -->  
<beans xmlns="http://www.springframework.org/schema/beans"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
    xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"    
    xsi:schemaLocation="    
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
    http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring  
    http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd">  
                                         
    <ehcache:annotation-driven />    
        
    <ehcache:config cache-manager="cacheManager">    
        <ehcache:evict-expired-elements interval="60" />    
    </ehcache:config>    
        
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">    
        <property name="configLocation"  value="classpath:spring/ehcache.xml"/>    
    </bean>  
</beans>  
 
    2. web.xml
Xml代码  收藏代码
<context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>classpath:spring/applicationContext.xml,classpath:spring/ehcacheApplication.xml</param-value>  
    </context-param>  
 
    3.   ehcache.xml
Xml代码  收藏代码
<?xml version="1.0" encoding="UTF-8"?>  
<!--   
/**  
 *   
 * 缓存配置  
 * @author zyz   
 * @date 2013年7月2日  
 *   
 */ -->  
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">    
        
    <diskStore path="user.home/web_ehcache/" />     
        
    <defaultCache    
            maxElementsInMemory="3000"    
            eternal="false"    
            timeToIdleSeconds="3600"    
            timeToLiveSeconds="3600"    
            overflowToDisk="true"    
            diskPersistent="false"    
            diskExpiryThreadIntervalSeconds="100"    
            memoryStoreEvictionPolicy="LRU"    
            />    
    <cache name="mallListCache"    
           maxElementsInMemory="3000"    
           eternal="false"    
           overflowToDisk="true"    
           timeToIdleSeconds="36000"    
           timeToLiveSeconds="36000"    
           memoryStoreEvictionPolicy="LFU"    
            />    
</ehcache>  
 
3.      代码

1.  缓存
 
给你需要缓存的方法加上如下这句
 
Java代码  收藏代码
@Cacheable(cacheName = "mallListCache")  
public int find() {  
 List<MallBean> list=mallDao.findMallResBean();  
    Return list.size();  
}  
  
cacheName里面对应ehcache.xml中配置的<cache name="mallListCache"  ,
 
这里我想说,网上很多人都是加到dao上的,我是直接加到service(业务层)里面的方法上,因为我的业务层方法会对数据做处理,而我需要缓存整个处理结果,所以加到service里面的方法上是可以的。
 
   2. 清除缓存
 
Java代码  收藏代码
@TriggersRemove(cacheName="mallListCache",removeAll=true)   
    public void flush(){  
       log.info("清除缓存!");  
    }  
  
cacheName里面对应缓存里面的名称,removeAll=true 这句是必须加的,否则无法清除缓存。
4.      测试

    1.     我的测试方法是,在控制层提供了两个方法,缓存和清除缓存,分别调用service中的两个方法find与flush,缓存方法将service中返回的size返给页面,在浏览器里面去请求这两个方法。
 
    2.    首次请求缓存方法,发现后台打印sql查询信息,再在数据库中添加数据,再次请求缓存方法,发现后台不打印sql查询信息,页面显示list的size不变。证明缓存成功。
 
    3.    请求清除缓存方法。
 
    4.   再次请求缓存方法,会发现后台打印sql查询信息,页面显示list的size发生变化。证明清除缓存成功。
 
 

对于这种方式,这里不做详细探讨。
在Spring 3.1以前,必须借助以上jar包才能支持以注解的方式使用缓存,但是从Spring 3.1开始,已经提供了原生的注解支持,当然也更加强大。
 
 
 
Spring 3.1及以上版本的原生注解支持

Spring配置文件:
<?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.xsd
          http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
 
      <cache:annotation-driven cache-manager ="ehcacheCacheManager" />
      <bean id = "ehcacheCacheManager" class= "org.springframework.cache.ehcache.EhCacheCacheManager"
           p:cacheManager-ref= "ehcacheManager" />
      <bean id = "ehcacheManager"
           class= "org.springframework.cache.ehcache.EhCacheManagerFactoryBean" >
           <property name = "configLocation" value= "classpath:ehcache.xml" />
      </bean>
</beans>
 

 
Spring原生的缓存的注解共有四个:
  • @Cacheable  :应用到读取数据的方法上,即可缓存的方法,如查找方法:先从缓存中读取,如果没有再调用方法获取数据,然后把数据添加到缓存中
  • @CacheEvict :即应用到移除数据的方法上,如删除方法,调用方法时会从缓存中移除相应的数据
  • @CachePut   :应用到写数据的方法上,如新增/修改方法,调用方法时会自动把相应的数据放入缓存
  • @Caching    :上面三种注解配置方法时,一个方法只能使用三者之一。如果要使用多个,则需要使用@Caching
 
 
前奏:缓存的key的生成:

如果在Cache注解上没有指定key的话,会使用KeyGenerator生成一个key,默认提供了DefaultKeyGenerator生成器(Spring4之后使用SimpleKeyGenerator)。
如果只有一个参数,就使用该参数作为key,否则使用SimpleKey作为key。
可以在Cache注解上指定key的生成规则,通过SpEL表达式指定规则。详细可以参考:Spring Cache抽象详解
如果没有入参,又没有指定key,那么key将是“SimpleKey []”,这将很容易造成缓存的混乱,而且也不利于在更新的时候进行缓存的更新或移除
 

在查询的方法上使用缓存:

@Cacheable(value="platform.config" )
public String querySingleConfigValue(String configKey) {
指定key的生成规则:
@Cacheable(value="platform.config", value="#configKey")
public String querySingleConfigValue(String configKey) {
 
 
在更新的方法上更新缓存:

@CachePut(value=PlatformPrivateConstants.CACHE_NAME_CONFIG, key="#config.configKey")
public SystemConfig updateConfig(SystemConfig config) {
 
通过"#config.configKey"指定以入参config对象的configKey属性值作为缓存的key。
更新的方法必须将要缓存的对象作为返回值,只有这个返回的对象才会放入缓存中,如果在返回值被返回之前篡改了其内部数据,也会被反映到缓存中。
 
 
指定正确的key以防止缓存混乱:

下面两个方法,前者通过configKey查询对象,后者通过configKey查询对象中的configValue属性值:
public SystemConfig querySingleConfig(String configKey) {
public String querySingleConfigValue(String configKey) {
 
如果不指定key,或者使用相同的key,比如:
@Cacheable(value="platform.config")
public SystemConfig querySingleConfig(String configKey) {
@Cacheable(value="platform.config")
public String querySingleConfigValue(String configKey) {
如果以"DEVELOPER_NAME"作为configKey分别调用这两个方法,那么,先调用哪个方法,则那个方法的返回值会以"DEVELOPER_NAME"作为key存入缓存中,此时调用这两个方法时都会从缓存中取得这个值。比如先调用了querySingleConfig方法,那么查询到的SystemConfig对象就会以"DEVELOPER_NAME"为key存入缓存中,然后调用querySingleConfigValue方法,因为仍会以"DEVELOPER_NAME"作为key从缓存中提取数据,这时就会从缓存中取得了刚才那个SystemConfig对象,却当作是字符串型的configValue属性值返回了。
 
所以比如为这两个方法指定不同的缓存key:
@Cacheable(value="platform.config", key = "#configKey.concat('_object'))
public SystemConfig querySingleConfig(String configKey) {
@Cacheable(value="platform.config")
public String querySingleConfigValue(String configKey) {
 
这样前者使用入参configKey值后接"_object"作为key,而后者使用入参configKey值为key,就不会相互覆盖了。
 
 
在更新的方法上同时更新多个缓存:

在查询时,可能通过id查询也可能通过name查询,这样在缓存中就存有两份数据,在更新的时候就必须同时更新这两份缓存。
@Cacheable(value="platform.config", key = "#configId)
public SystemConfig querySingleConfig(long configId) {
@Cacheable(value="platform.config", key = "#configKey)
public SystemConfig querySingleConfig(String configKey) {
 
通过@Caching注解组合多个@CachePut注解,从而在调用更新方法时同时更新多份缓存(以不同的key存在于缓存中)
@Caching(put={@CachePut(value="platform.config" , key="#config.configId"),
              @CachePut(value="platform.config" , key="#config.configKey" )})
public SystemConfig updateConfig(SystemConfig config) {
 
 
在更新方法上同时更新和清除缓存:

上面的方法虽然可以同时更新多个缓存,但是必须保证这些缓存的值是完全一样的,比如上面两个方法缓存的都是SystemConfig对象,而对于下面的方法就无能为力了,因为下面的方法缓存的是SystemConfig对象的configValue属性值,而上面的方式只能把作为返回值的SystemConfig对象更新到缓存中。
@Cacheable(value="platform.config")
public String querySingleConfigValue(String configKey) {
 
对于这种情况,通过@CacheEvict清除那些无法更新的缓存,这样下次获取不到这些缓存就会越过缓存从数据库查询最新的数据。
@Caching(evict={@CacheEvict(value="platform.config", key="#config.configKey" )},
         put={@CachePut(value="platform.config", key="#config.configId.concat('_object')"),
              @CachePut(value="platform.config", key="#config.configKey.concat('_object')" )})
public SystemConfig updateConfig(SystemConfig config) {
 
 
使用缓存的业务层的设计宗旨:

使用缓存的业务类应尽量精简、方法应尽可能少,只保留最紧要的方法。
因为进行更新操作时需要考虑每一个的获取数据的方法,必须将可能被更新操作波及的所有缓存进行更新或清除,如果获取数据的方法过多,这个工作量将变得很大,并且很容易出错,比如忘记了更新或清除某一份缓存,而大型项目中这种错误可能难以被发现。
分享到:
评论

相关推荐

    spring + ehcache + redis两级缓存

    在Spring中,我们可以配置Ehcache作为缓存 provider,通过注解或XML配置来启用和管理缓存。 **Redis** 是一个高性能的键值数据库,常被用作分布式缓存系统。相比于Ehcache,Redis支持更丰富的数据结构(如字符串、...

    Spring + Ehcache 注解形式配置

    本文将深入探讨如何在Spring框架中通过注解方式配置Ehcache,以便优化应用程序的性能。 首先,让我们理解Spring与Ehcache结合的基本概念。Ehcache是一个内存缓存系统,它可以存储数据到内存中,从而减少数据库的...

    spring+ehcache示例整合Demo

    在这个"spring+ehcache示例整合Demo"中,我们将会探讨如何将Ehcache集成到Spring框架中,以实现高效的缓存管理。 首先,我们需要在项目的`pom.xml`文件中引入Ehcache和Spring的依赖。Ehcache通常使用的是`org....

    Struts2+Spring+Hibernate+Ehcache+AJAX+JQuery+Oracle 框架集成用户登录注册Demo工程

    1.通过google ehcache-spring-annotatios.jar自动注解方式实现整合Spring+Ehcache。 2.Action里通过struts2-spring-plugin.jar插件自动根据名字注入。 3.Ajax无刷新异步调用Struts2,返回Json数据,以用户注册为例。...

    spring3.2+ehcache 注解使用

    在本文中,我们将深入探讨如何在Spring 3.2框架中使用Ehcache注解进行缓存管理。Ehcache是一种流行的Java缓存解决方案,它能够显著提高应用程序的性能,尤其是在处理频繁读取但更新不频繁的数据时。Spring 3.2引入了...

    Spring 与Ehcache实现基于方法的缓存

    在Spring的配置文件中,启用缓存注解支持,并指定使用的缓存管理器。例如,使用`&lt;cache:annotation-driven&gt;`标签: ```xml &lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi=...

    Spring+EhCache缓存实例

    **Spring+EhCache缓存...总结,Spring与EhCache的结合提供了强大的缓存能力,通过合理的配置和使用,可以显著提高系统的响应速度,减轻数据库压力。理解并熟练掌握这些知识点,对于构建高效率、高性能的应用至关重要。

    spring+ehcache demo

    总结,这个"spring+ehcache demo"是一个全面的示例,涵盖了从引入Ehcache依赖、配置Spring Cache到编写缓存注解的方法。通过学习和实践这个示例,开发者可以深入了解Spring与Ehcache的集成,以及如何利用缓存提升...

    Spring+Ehcache集成

    本篇文章将详细介绍如何在Spring项目中集成Ehcache,以及如何通过Spring的AOP(面向切面编程)实现方法级别的缓存注解。 首先,我们需要在项目中引入Ehcache的依赖。通常,这可以通过在`pom.xml`文件中添加Maven...

    spring+ibatis+ehcache整合例子

    Ehcache的配置包括在Spring配置文件中声明CacheManager,以及定义需要缓存的bean和对应的缓存策略。 4. **编写Mapper接口和XML映射文件** iBatis中的Mapper接口对应数据库操作,XML映射文件定义了SQL语句和结果...

    spring+ehcache完整示例demo

    在IT行业中,Spring框架是Java领域最常用的轻量级应用框架之一,而Ehcache则是一种广泛使用的内存缓存系统,常与Spring搭配用于提升应用性能。本示例旨在通过一个完整的Spring集成Ehcache的Demo,帮助开发者理解如何...

    springMVC+mybatis+ehcache整合

    在Spring中整合Ehcache,可以通过Spring的缓存抽象进行配置,定义缓存注解如`@Cacheable`、`@CacheEvict`、`@CachePut`来控制缓存的存取和清除。Ehcache的配置文件(ehcache.xml)可以指定缓存的大小、存活时间和...

    Spring+Hibernate+ehcache整合

    1. **Spring配置**:Spring的配置文件(如`applicationContext.xml`)会定义bean,包括数据源、SessionFactory(Hibernate)、缓存管理器(Ehcache)以及业务层和服务层的组件。通过依赖注入,Spring将这些组件装配...

    Ehcache(一): Spring + Ehcache开场白

    配置Ehcache,我们可以在Spring的配置文件中定义一个`CacheManager` bean,指定Ehcache的配置文件路径。Ehcache的配置文件(如ehcache.xml)包含了缓存的命名空间、大小限制、过期策略等信息。例如: ```xml ...

    Spring+ehcache整合

    在IT行业中,Spring框架是Java企业级应用开发的首选,而Ehcache则是一款广泛使用的内存缓存系统,尤其在处理大数据量、高并发场景下,能够显著提升系统的响应速度和性能。本教程将深入探讨如何在Spring 4.1版本中...

    spring+ehcache

    - 配置Ehcache:创建`ehcache.xml`配置文件,设置缓存策略、大小等参数。 - 配置Spring:在Spring配置文件中启用缓存管理器,并指定使用Ehcache。 - 使用注解:在需要缓存的方法上添加`@Cacheable`、`@CacheEvict...

    SpringMVC+Mybatis+Spring+Shiro+ehcache整合配置文件

    Ehcache可以很好地与Spring集成,通过简单的配置即可实现缓存管理。 在整合这些技术时,首先需要在Spring的配置文件中定义bean,包括数据源、SqlSessionFactory(Mybatis的核心)、MapperScannerConfigurer(扫描...

    Spring AOP+ehCache简单缓存系统解决方案

    在`ehcache.xml`文件中,我们可以配置缓存的详细设置,包括缓存的大小、存活时间和过期策略。例如: ```xml &lt;ehcache&gt; &lt;/ehcache&gt; ``` 这个配置创建了一个名为“myCache”的缓存,最大可以在堆内存中存储100...

Global site tag (gtag.js) - Google Analytics