`
collegeyuan
  • 浏览: 31185 次
  • 性别: Icon_minigender_2
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

spring缓存

 
阅读更多

Spring缓存

    spring缓存可以对容器中的任意bean或bean的方法增加缓存。

启用spring缓存

   导入cache:命名空间之后,启动spring环境还要两步:

    1)在spring配置文件中添加<cache:annotation-driven cache-manager="缓存管理器ID"/>,该元素指定spring根据注解来启动Bean级别或方法级别的缓存。

     2)针对不同的缓存实现配置对应的缓存管理器。

第一步中,<cache:annotation../>通过cache-manager显示指定容器中缓存管理器ID,改属性默认值是cacheManager,也就是说,如果容器中缓存管理器ID设为cacheManager,则可省略<cache:annotation../>的cache-manager属性。

 

下面是spring内置缓存实现和EHcache缓存实现

一、spring内置缓存实现

      spring内置缓存实现只是一种内存中的缓存,并非真正的缓存实现,因此通常只用于简单的测试环境,实际项目中不建议用。

     Spring内置的缓存实现使用SimpleCacheManager作为缓存管理器,使用SimpleCacheManager配置缓存非常简单,直接在spring容器中配置改Bean,然后通过<property../>驱动改缓存管理器执行setCaches()方法来设置缓存区即可。

     SimpleCacheManager是一种内存中的缓存区,底层直接使用了JDK的ConcurrentMap来实现缓存,SimpleCacheManager使用了ConcurrentMapFactoryBean作为缓存区,每个ConcurrentMapFactoryBean配置一个缓存区。

     以下是spring内置缓存的缓存管理器配置。

     <bean id="cacheManager" class=

         "org.springframework.cache.support.SimpleCacheManager">

         <!-- 配置缓存区-->

         <property name="caches">

               <set>

                      <!--  使用ConcurrentMapFactoryBean配置缓存区,下面列出多个

                              缓存区,P:name用于缓存区指定名字  -->

                      <bean class=

                          "org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"

                          p:name="default"/>

                      <bean class = 

                           "org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"

                          p:name="users"/>

            </property>

     </bean>

以上配置了两个缓存区,default、users。缓存区名字很重要,后面使用注解驱动缓存时需要根据缓存区名字来指定将缓存数据放入指定的缓存区。

 

二、EHcache缓存实现

     前期准备:

          将ehcache-core-2.3.4.jar、slf4j-api-1.6.1.jar放到lib目录下

    1)在类路径下添加一个ehcache.xml配置文件。配置如下:

           <ehcache>

 

                 <diskStore path="java.io.tmpdir"/>

                     <defaultCache

                         maxElementsInMemory="10000"

                         eternal="false"

                         overflowToDisk="true"

                         memoryStoreEvictionPolicy="LRU"

                         timeToIdLeSeconds="120"

                         timeToLiveSeconds="120"

                         maxElementsOnDisk="10000000"

                         diskExpiryThreadIntervalSeconds="120"

                         />

    

                     <cache name="users"

                         maxElementsInMemory="10000"

                         eternal="false"

                         overflowToDisk="true"

                         memoryStoreEvictionPolicy="LRU"

                         timeToIdLeSeconds="120"

                         timeToLiveSeconds="120"

                         maxElementsOnDisk="10000000"

                         diskExpiryThreadIntervalSeconds="120"

                 </ehcache>

         以上配置了两个缓存区,一个匿名的、默认的缓存区。一个是名为users的缓存区。

        

         2)、在spring配置文件中添加下配置:

              在<beans>中引入p:命名空间

               xmlns:p="http://www.springframework.org/schema/p"

 

             <!-- 配置Ehcache的CacheManager 

                   通过configLocation指定ehcache.xml文件的位置 -->

             <bean id="ehCacheManager"

                    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean“

                    p:configLocation="classpath:ehcache.xml"

                    p:shared="false"/>

              <!-- 配置基于EhCache的缓存管理器

                    并将EhCache的CacheManager注入改缓存管理器Bean-->

               <bean id="cacheManager"

                      class="org.springframework.cache.ehcache.EhCacheManager"

                      p:cacheManager-ref="ehCacheManger"/>

           

             上面配置文件中,第一个Bean是一个工厂Bean,它用于配置EhCache的CacheManager;第二个Bean才是spring缓存配置的基于EhCache的缓存管理器,改缓存器需要依赖于ehCacheManager,因此将第一个Bean注入到第二个Bean中。

 

三、使用@Cacheable执行缓存   (以下实例将应用一、二中配置的缓存管理器)

    @Cacheable可用于修饰类或修饰方法。但使用@Cacheable修饰类时,用于告诉Spring在类级别上进行缓存——程序调用该类的任何方法时都需要缓存,而且共享一个缓存区;当使用@Cacheable修饰方法时,只有当程序调用改方法时才需要缓存。

 

1、类级别的缓存

      使用@Cacheable修饰类是,控制spring在类级别进行缓存。这样当程序调用该类的任意方法时,只要传入参数相同,spring就会缓存。

     程序清单

     @Service("userService")

     @Cacheable(value="users")  //@Cacheable(value="users" key="#name")

     public class UserServiceImpl implements UserService{

          public User getusersByNameAndAge(String name,int age){

                 System.out.println("--正在执行getusersByNameAndAge方法--”);

                  return new User(name,age);

          }

          public User getAnotherUser(String name,int age){

              System.out.println("--正在执行getAnotherUser方法--”);

                  return new User(name,age);

           }

    }

   程序清单:

             public class SpringTest{

               public static void main(String[] args){

                    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");

                    UserService us = ctx.getBean("userService“,UserService.class);

                    User u1= us.getusersByNameAndAge("孙悟空”,500);

                    User u2= us.getAnotherUser("孙悟空”,500);

                    System.out.println(u1==u2);

               }

执行结果如下:

            --正在执行getusersByNameAndAge方法--

             true

      从结果可看出,程序并未调用getAnotherUser方法。由此可见,类级别的缓存默认以所有的参数作为key来缓存方法返回的数据——同一个类中,不管调用哪个方法,只要调用方法传入的参数相同,spring都会直接利用缓存区中的数据。

       @Cacheable有以下几个属性:

           value:必须属性。用于指定多个缓冲区的名字。指定返回方法的数据放在哪个缓存区。

           key:通过SpEL表达式指定缓存的Key。(调用方法是否需要重复执行,看key。key值默认为所有参数)

          condition:该属性返回一个boolean值的SpEL表达式

 2、类级别的缓存

       使用@Cacheable修饰方法时,就可控制spring在方法级别的缓存,这样当程序调用该方法时,只要传入的参数相同,spring就会使用缓存。

      @Service("userService")

      public  class UserServiceImpl implements UserService{

                 @Cacheable(value="users1")

                 public User getUsersByNameAndAge(String name,int age){

                       System.out.println("--正在执行 getUsersByNameAndAge查询方法--”);

                        return new User(name,age);

                  }

                 @Cacheable(value="user2")

                  public User getAnotherUser(String name,int age){

                            System.out.println("--正在执行 getAnotherUser查询方法--”);

                             return new User(name,age);

                  }

            } 

     程序清单:

             public class SpringTest{

               public static void main(String[] args){

                    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");

                    UserService us = ctx.getBean("userService“,UserService.class);

                    User u1= us.getusersByNameAndAge("孙悟空”,500);

                    User u2= us.getAnotherUser("孙悟空”,500);

                    System.out.println(u1==u2);

                   User u3= us.getAnotherUser("孙悟空”,500);

                    System.out.println(u2==u3);

               }

执行结果:

    --正在执行 getUsersByNameAndAge查询方法--

    --正在执行 getAnotherUser查询方法--

    false

    true

三、清除缓存区

       被@CacheEvict注释修饰的方法用于清除缓存,@CacheEvict有如下几个注解:

           value:必须属性,用于指定该方法用于清除哪个缓存区中的数据。

           allEntries:该属性指定是否清除整个缓存区

           beforeInvocation:该属性指定是否在执行方法之前清除缓存。默认是在方法成功完成之后才清缓存。

           condition:只有满足条件是,才清除缓存。

           key:指定key,清除指定缓存的key

           程序清单:

               @Service("userService")

      @Cacheable(value="users")

      public  class UserServiceImpl implements UserService{

                 

                 public User getUsersByNameAndAge(String name,int age){

                       System.out.println("--正在执行 getUsersByNameAndAge查询方法--”);

                        return new User(name,age);

                  }

              

                  public User getAnotherUser(String name,int age){

                            System.out.println("--正在执行 getAnotherUser查询方法--”);

                             return new User(name,age);

                  }

                 @CacheEvict(value="users")

                 public void evictUser(String name,int age){

                          System.out.println("--正在清除”+name+","+age+"对应的缓存区--");

                 }

                @CacheEvict(value="users",allEntries= true)

                 public void evictAll(String name,int age){

                          System.out.println("--正在清除整个缓存区--");

 

                 }

            } 

     程序清单:

             public class SpringTest{

               public static void main(String[] args){

                    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");

                    UserService us = ctx.getBean("userService“,UserService.class);

                    User u1= us.getusersByNameAndAge("孙悟空”,500);

                    User u2= us.getAnotherUser("猪八戒”,400);

                   us.evictUser("猪八戒”,400);

                   //"猪八戒”,400缓存区中数据被清除

                     User u3= us.getAnotherUser("猪八戒”,400);

                    System.out.println(u2==u3);

                     User u4= us.getAnotherUser("孙悟空”,500);

                    System.out.println(u1==u4);

                     us.evictAll();

                    User u5= us.getAnotherUser("孙悟空”,500);

                    User u6= us.getAnotherUser("猪八戒”,400);

                   System.out.println(u1==u5);

                    System.out.println(u3==u6);

 

               }

 

执行结果:

    --正在执行 getUsersByNameAndAge查询方法--

    --正在执行 getAnotherUser查询方法--

    --正在清除猪八戒,400对应的缓存---

     --正在执行 getAnotherUser查询方法--

    false

     true

      --正在清空整个缓存区--

        --正在执行 getAnotherUser查询方法--

   --正在执行 getAnotherUser查询方法--

   false

   fasle

           

分享到:
评论

相关推荐

    Spring 缓存

    Spring 缓存机制详解 Spring 缓存机制是 Spring 框架中的一种机制,用于提高应用程序的性能和效率。缓存机制可以将频繁访问的数据存储在内存中,以便快速地检索数据,减少数据库查询的次数,从而提高应用程序的性能...

    spring缓存机制-根据condition加入缓存(三)

    ### 一、Spring缓存概述 Spring框架提供了一种统一的缓存抽象,支持多种缓存实现,如EhCache、Hazelcast、Infinispan、Guava等。通过`@EnableCaching`注解开启缓存功能,并使用`@Cacheable`、`@CacheEvict`、`@...

    spring缓存实例

    其中,Spring缓存机制是提高应用程序性能的关键特性,尤其对于数据密集型应用而言。本篇将深入探讨Spring缓存实例,基于给出的博客链接(http://blog.csdn.net/maoyeqiu/article/details/50433934)和文件"20140527...

    spring缓存机制-入门实例

    本篇文章将深入探讨Spring缓存机制的基础知识,并通过一个入门实例来阐述其工作原理和使用方法。 Spring缓存抽象是自Spring 3.1版本引入的,它提供了一个统一的API,支持多种缓存解决方案,如EhCache、Guava Cache...

    Spring缓存配置

    **Spring缓存配置详解** 在Java Web开发中,Spring框架以其强大的功能和灵活性深受开发者喜爱。其中,Spring的缓存管理是提升应用性能的关键部分,它允许我们将经常访问但变化不频繁的数据存储在内存中,以减少对...

    spring缓存机制-自定义缓存(五, 六)

    在“spring缓存机制-自定义缓存(五, 六)”中,我们将深入探讨如何扩展Spring的缓存功能,使其更加灵活且功能丰富。 一、Spring缓存抽象 Spring缓存抽象是基于Java的注解驱动的,它提供了声明式缓存管理。核心组件...

    Spring缓存

    首先,让我们理解Spring缓存的概念。Spring Cache是一个模块,它允许你在应用中添加统一的缓存抽象,无需关心具体实现。通过在方法上添加注解,如`@Cacheable`、`@CacheEvict`等,可以轻松地启用和管理缓存,提高...

    spring缓存机制-@CachePut的用法(四)

    总结起来,`@CachePut`注解在Spring缓存机制中扮演着重要角色,它确保了方法的执行,并将结果存入缓存,即使缓存中已有对应键的条目。通过合理配置和使用,可以有效提升应用性能,同时保证数据的实时性。在实际项目...

    spring简单的缓存

    本示例将聚焦于“Spring简单的缓存”实现,帮助开发者了解如何在Spring框架中集成和使用缓存功能。 Spring框架提供了强大的缓存抽象,支持多种缓存机制,如 EhCache、Redis、Hazelcast 和 Infinispan 等。在Spring...

    Spring 缓存抽象示例详解

    Spring 缓存抽象是Spring框架从3.1版本开始引入的一种功能,旨在提供一种统一的方式来管理和集成各种缓存实现,如EhCache、Hazelcast、Infinispan和Redis等。这一抽象使得开发者能够在不关注具体缓存实现的情况下,...

    基于Spring的Web缓存

    在实现Spring缓存时,你需要确保引入了相应的库,如`spring-boot-starter-cache`或`spring-context-support`,它们包含了Spring缓存支持所需的类和接口。同时,如果你打算使用特定的缓存实现,如EhCache或Redis,还...

    spring自动加载缓存

    一、Spring缓存抽象 1. **@Cacheable**:这是最常用的注解,用于标记那些可以被缓存的方法。当方法被调用时,Spring会检查缓存中是否存在对应的结果,如果存在则直接返回,无需再次执行方法;如果不存在,执行方法...

    详解Spring缓存注解@Cacheable,@CachePut , @CacheEvict使用

    Spring 缓存注解 @Cacheable、@CachePut、@CacheEvict 使用详解 Spring 框架提供了三个缓存注解:@Cacheable、@CachePut 和 @CacheEvict,这三个注解可以帮助开发者简化缓存的使用,提高应用程序的性能。在本文中,...

    Spring缓存机制实例代码

    Spring缓存机制是Spring框架提供的一种高级特性,用于在应用程序中实现数据的缓存,从而提高性能和减少数据库的负载。它允许开发者在不修改业务逻辑的情况下,轻松地在应用的不同层次引入缓存功能。本文将深入探讨...

    spring缓存代码详解

    Spring 缓存是一种高效的方法,用于提升应用程序性能和减轻服务器负担。从Spring 3.1开始,Spring引入了声明式的缓存管理API,类似于声明式事务管理。它提供了一个抽象接口,可以统一处理不同的缓存解决方案,使得...

    Spring 缓存的资料整理

    博文链接:https://melin.iteye.com/blog/80650

Global site tag (gtag.js) - Google Analytics