最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring緩存機制實例代碼

 更新時間:2018年02月08日 10:11:23   作者:云中之歌  
這篇文章主要介紹了Spring緩存機制實例代碼,分享了相關代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下

Spring的緩存機制非常靈活,可以對容器中任意Bean或者Bean的方法進行緩存,因此這種緩存機制可以在JavaEE應用的任何層次上進行緩存。

Spring緩存底層也是需要借助其他緩存工具來實現(xiàn),例如EhCache(Hibernate緩存工具),上層則以統(tǒng)一API編程。

要使用Spring緩存,需要以下三步

  • 1.向Spring配置文件導入context:命名空間
  • 2.在Spring配置文件啟用緩存,具體是添加 <cache:annotation-driven cache-manager="緩存管理器ID" />
  • 3.配置緩存管理器,不同的緩存實現(xiàn)配置不同,如果是EhCache,需要先配置一個ehcache.xml

例如

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
  <diskStore path="java.io.tmpdir" />
  <!-- 配置默認的緩存區(qū) -->
  <defaultCache
    maxElementsInMemory="10000"
    eternal="false"
    timeToIdleSeconds="120"
    timeToLiveSeconds="120"
    maxElementsOnDisk="10000000"
    diskExpiryThreadIntervalSeconds="120"
    memoryStoreEvictionPolicy="LRU"/>
  <!-- 配置名為users的緩存區(qū) -->
  <cache name="users"
    maxElementsInMemory="10000"
    eternal="false"
    overflowToDisk="true"
    timeToIdleSeconds="300"
    timeToLiveSeconds="600" />
</ehcache>

上面的ehcache.xml配置了兩個緩存區(qū),Spring中的Bean將會緩存在這些緩存區(qū)中,一般的,Spring容器中有多少個Bean,就會在ehcache中定義多少個緩存區(qū)。

接著在Spring配置文件中配置緩存管理器如下,其中第一個Bean是一個工廠Bean,用來配置EhCache的CacheManager, 第二個Bean才是為Spring緩存配置的緩存管理器,所以將第一個Bean注入第二個Bean。

<cache:annotation-driven cache-manager="cacheManager" />

  <!-- 配置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.EhCacheCacheManager"
    p:cacheManager-ref="ehCacheManager" > 
  </bean>

下面是一個完整的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:p="http://www.springframework.org/schema/p"
  xmlns:cache="http://www.springframework.org/schema/cache"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  http://www.springframework.org/schema/cache
  http://www.springframework.org/schema/cache/spring-cache-4.0.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-4.0.xsd">

  <context:component-scan 
    base-package="com.service"/>
    
  <cache:annotation-driven cache-manager="cacheManager" />

  <!-- 配置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.EhCacheCacheManager"
    p:cacheManager-ref="ehCacheManager" > 
  </bean>
  
</beans>

下面將以@Cacheable為例,演示Spring基于EhCache緩存的用法。 Cacheable用于修飾類或者方法,如果修飾類,則類中所有方法都會被緩存。

類級別的緩存

例如有如下Bean類,

@Service("userService")
@Cacheable(value="users")
public class UserServiceImpl implements UserService {

  @Override
  public User getUsersByNameAndAge(String name, int age) {
    System.out.println("正在執(zhí)行getUsersByNameAndAge()..");
    return new User(name,age);
  }

  @Override
  public User getAnotherUser(String name, int age) {
    System.out.println("正在執(zhí)行getAnotherUser()..");
    return new User(name,age);
  }
}

基于類的緩存,將會緩存類中的所有方法,緩存之后,程序調(diào)用該類實例的任何方法,只要傳入的參數(shù)相同,Spring將不會真正執(zhí)行該方法,而是直接根據(jù)傳入的參數(shù)去查找緩存中的數(shù)據(jù)!

比如像下面這樣使用緩存數(shù)據(jù),

public static void test2() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    UserService us = ctx.getBean("userService", UserService.class);
    User u1 = us.getUsersByNameAndAge("張三", 50);
    //由于第二次調(diào)用userService方法時,使用了相同參數(shù),那么真正的方法將不會執(zhí)行,
    //Spring將直接從緩存按參數(shù)查找數(shù)據(jù)
    User u2 = us.getAnotherUser("張三", 50);
    System.out.println(u1==u2);
  }

輸出結果,

正在執(zhí)行getUsersByNameAndAge()..
true

可以看到,上面的getAnotherUser()并沒有真正執(zhí)行,因為傳入的參數(shù)與之前的方法傳入的參數(shù)相同,于是Spring直接從緩存區(qū)數(shù)據(jù)了。

上面的Bean類中的注解@Cacheable除了必選屬性value之外,還有key, condition,, unless屬性,后面三個都是用來設置Spring存儲策略,對于基于類的緩存來說,Spring默認以方法傳入的參數(shù)作為key去緩存中查找結果。

當然我們也可以修改key的策略,讓Spring按照其他標準,比如按照第一個參數(shù)是否相同來作為key,在緩存中查找結果。

將上面的Bean類修改如下,

@Service("userService")
@Cacheable(value="users", key="#name")
public class UserServiceImpl implements UserService {

  @Override
  public User getUsersByNameAndAge(String name, int age) {

意味著我們傳入相同的name,Spring就不會真正執(zhí)行方法。只有name不同的時候,方法才會真正執(zhí)行,例如下面,

public static void test2() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    UserService us = ctx.getBean("userService", UserService.class);
    User u1 = us.getUsersByNameAndAge("張三", 50);
    //將@Cacheable的key參數(shù)改為key="#name"之后,下面的方法將可以執(zhí)行。
    User u2 = us.getAnotherUser("李四", 50);
    System.out.println(u1==u2);
  }

可以看到這回getAnotherUser()方法得到執(zhí)行了,

1 正在執(zhí)行getUsersByNameAndAge()..
2 正在執(zhí)行getAnotherUser()..
3 false

我們也可以設置condition屬性,例如,

@Service("userService")
@Cacheable(value="users", condition="#age<100")
public class UserServiceImpl implements UserService {

  @Override
  public User getUsersByNameAndAge(String name, int age) {

那么對于下面的代碼來說,兩個方法都不會被緩存,Spring每次都是執(zhí)行真正的方法取結果,

public static void test2() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    UserService us = ctx.getBean("userService", UserService.class);
    User u1 = us.getUsersByNameAndAge("張三", 500);
    User u2 = us.getAnotherUser("李四", 500);
    System.out.println(u1==u2);
  }

執(zhí)行結果,

正在執(zhí)行getUsersByNameAndAge()..
正在執(zhí)行getAnotherUser()..
false

方法級別的緩存

方法級別的緩存則只會對方法起作用了,不同的方法可以設置不用的緩存區(qū),例如下面這樣,

@Service("userService")
public class UserServiceImpl implements UserService {

  @Cacheable("users1")
  @Override
  public User getUsersByNameAndAge(String name, int age) {
    System.out.println("正在執(zhí)行getUsersByNameAndAge()..");
    return new User(name,age);
  }

  @Cacheable("users2")
  @Override
  public User getAnotherUser(String name, int age) {
    System.out.println("正在執(zhí)行getAnotherUser()..");
    return new User(name,age);
  }
}

使用下面的測試代碼,

public static void test2() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    UserService us = ctx.getBean("userService", UserService.class);
    //第一次執(zhí)行方法,方法將會真正執(zhí)行并緩存
    User u1 = us.getUsersByNameAndAge("張三", 500);
    //雖然下面方法傳入相同參數(shù),但是因為這兩個方法在不同的緩存區(qū),所以無法使用緩存數(shù)據(jù)
    User u2 = us.getAnotherUser("張三", 500);
    System.out.println(u1==u2);
    //上面已經(jīng)緩存過,這里不會真正執(zhí)行,直接使用緩存
    User u3 = us.getAnotherUser("張三", 500);
    System.out.println(u3==u2);
  }

執(zhí)行結果,

正在執(zhí)行getUsersByNameAndAge()..
正在執(zhí)行getAnotherUser()..
false
true

使用@CacheEvict清除緩存

被@CacheEvict修飾的方法可以用來清除緩存,使用@CacheEvict可以指定如下屬性。

allEntries, 是否清空整個緩存區(qū)

beforeInvocation: 是否在執(zhí)行方法之前清除緩存。默認是方法執(zhí)行成功之后才清除。

condiition以及key, 與@Cacheable中一樣的含義。

下面示范簡單用啊,

@Service("userService")
@Cacheable("users")
public class UserServiceImpl implements UserService {
	@Override
	  public User getUsersByNameAndAge(String name, int age) {
		System.out.println("正在執(zhí)行getUsersByNameAndAge()..");
		return new User(name,age);
	}
	@Override
	  public User getAnotherUser(String name, int age) {
		System.out.println("正在執(zhí)行getAnotherUser()..");
		return new User(name,age);
	}
	//指定根據(jù)name,age參數(shù)清楚緩存
	@CacheEvict(value="users")
	  public void evictUser(String name, int age) {
		System.out.println("--正在清空"+name+","+age+"對應的緩存--");
	}
	//指定清除user緩存區(qū)所有緩存的數(shù)據(jù)
	@CacheEvict(value="users", allEntries=true)
	  public void evictAll() {
		System.out.println("--正在清空整個緩存--");
	}
}

下面是測試類,

public static void test2() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
    UserService us = ctx.getBean("userService", UserService.class);
    //系統(tǒng)會緩存兩個方法
    User u1 = us.getUsersByNameAndAge("張三", 500);
    User u2 = us.getAnotherUser("李四",400);
    //調(diào)用evictUser()方法清除緩沖區(qū)指定的數(shù)據(jù)
    us.evictUser("李四", 400);
    //前面清除了 李四, 400 的緩存,下面的方法返回的數(shù)據(jù)將會再次被緩存
    User u3 = us.getAnotherUser("李四", 400);
    System.out.println(us == u3);  //false
    //前面已經(jīng)緩存了 張三, 500的數(shù)據(jù),下面方法不會重新執(zhí)行,直接取緩存中的數(shù)據(jù)
    User u4 = us.getAnotherUser("張三", 500);
    System.out.println(u1==u4); //輸出true
    //清空整個緩存
    us.evictAll();
    //由于整個緩存都已經(jīng)被清空,下面的代碼都會被重新執(zhí)行
    User u5 = us.getAnotherUser("張三", 500);
    User u6 = us.getAnotherUser("李四", 400);
    System.out.println(u1==u5); //輸出false
    System.out.println(u3==u6); //輸出false
  }

執(zhí)行結果,

正在執(zhí)行getUsersByNameAndAge()..
正在執(zhí)行getAnotherUser()..
--正在清空李四,400對應的緩存--
正在執(zhí)行getAnotherUser()..
false
true
--正在清空整個緩存--
正在執(zhí)行getAnotherUser()..
正在執(zhí)行getAnotherUser()..
false
false

總結

以上就是本文關于Spring緩存機制實例代碼的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

相關文章

  • springboot啟動加載CommandLineRunner @PostConstruct問題

    springboot啟動加載CommandLineRunner @PostConstruct問題

    這篇文章主要介紹了springboot啟動加載CommandLineRunner @PostConstruct問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • SpringBoot使用?Sleuth?進行分布式跟蹤的過程分析

    SpringBoot使用?Sleuth?進行分布式跟蹤的過程分析

    Spring Boot Sleuth是一個分布式跟蹤解決方案,它可以幫助您在分布式系統(tǒng)中跟蹤請求并分析性能問題,Spring Boot Sleuth是Spring Cloud的一部分,它提供了分布式跟蹤的功能,本文將介紹如何在Spring Boot應用程序中使用Sleuth進行分布式跟蹤,感興趣的朋友一起看看吧
    2023-10-10
  • Spring中的策略模式簡單實現(xiàn)與使用分析

    Spring中的策略模式簡單實現(xiàn)與使用分析

    這篇文章主要介紹了Spring中的策略模式簡單實現(xiàn)與使用分析,去初始化時除了?initMultipartResolver(上傳文件)沒有獲取?Properties?defaultStrategies;默認策略,其他的八大件都會使用到策略模式,需要的朋友可以參考下
    2024-01-01
  • JavaEE組件commons-fileupload實現(xiàn)文件上傳、下載

    JavaEE組件commons-fileupload實現(xiàn)文件上傳、下載

    這篇文章主要介紹了JavaEE組件commons-fileupload實現(xiàn)文件上傳、下載,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Java利用EasyExcel讀取寫入Excel詳情

    Java利用EasyExcel讀取寫入Excel詳情

    這篇文章主要介紹了Java利用EasyExcel讀取寫入Excel詳情,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • java實現(xiàn)停車場系統(tǒng)

    java實現(xiàn)停車場系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)停車場系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • Java?常量池詳解之class文件常量池?和class運行時常量池

    Java?常量池詳解之class文件常量池?和class運行時常量池

    這篇文章主要介紹了Java?常量池詳解之class文件常量池?和class運行時常量池,常量池主要存放兩大類常量:字面量,符號引用,本文結合示例代碼對java class常量池相關知識介紹的非常詳細,需要的朋友可以參考下
    2022-12-12
  • Java中Object轉(zhuǎn)換為List類型的實現(xiàn)方法

    Java中Object轉(zhuǎn)換為List類型的實現(xiàn)方法

    這篇文章主要介紹了Java中Object轉(zhuǎn)換為List類型的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • SpringKafka消息發(fā)布之KafkaTemplate與事務支持功能

    SpringKafka消息發(fā)布之KafkaTemplate與事務支持功能

    通過本文介紹的基本用法、序列化選項、事務支持、錯誤處理和性能優(yōu)化技術,開發(fā)者可以構建高效可靠的Kafka消息發(fā)布系統(tǒng),事務支持特性尤為重要,它確保了在分布式環(huán)境中的數(shù)據(jù)一致性,感興趣的朋友一起看看吧
    2025-04-04
  • Java多線程工具篇BlockingQueue的詳解

    Java多線程工具篇BlockingQueue的詳解

    今天小編就為大家分享一篇關于Java多線程工具篇BlockingQueue的詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-03-03

最新評論

淅川县| 石屏县| 新邵县| 海兴县| 青川县| 南京市| 西丰县| 静海县| 同仁县| 中宁县| 比如县| 平山县| 河间市| 抚顺县| 蕉岭县| 桃园市| 枝江市| 通道| 霍山县| 兰溪市| 吉木乃县| 吉木乃县| 文昌市| 砚山县| 乌鲁木齐县| 宜城市| 上林县| 通江县| 东阿县| 鄄城县| 沙河市| 搜索| 洛浦县| 张北县| 淮阳县| 汨罗市| 房产| 横山县| 镇赉县| 青岛市| 商洛市|