1.spring從3.1開始支持緩存功能。spring 自帶的緩存機制它只在方法上起作用,對於你使用其他持久化層的框架來講,是沒有影響的,相對來講這種緩存方式還是不錯的選擇。
2.提供緩存的接口:org.springframework.cache.Cache ;org.springframework.cache.CacheManager這兩個接口都在context中,一個是用來提供緩存的,一個是用來提供管理緩存的。
3.緩存是使用鍵值對的形式存在的,對應Java中就要使用Map<K,V>這種數據結構來處理,推薦使用java.util.concurrent.ConcurrentMap來存放。
4.注解:
在上面的注解中我們常用到的有@Cacheable,@CacheEvict,@CachePut這3個,我們目前也只學這3個
5.
@Cacheable:用來定義緩存的。常用到是value,key;分別用來指明緩存的名稱和方法中參數,對於value你也可以使用cacheName,在查看源代碼是我們可以看到:兩者是指的同一個東西。
@CacheEvict:用來清理緩存。常用有cacheNames,allEntries(默認值false);分別代表了要清除的緩存名稱和是否全部清除(true代表全部清除)。
@CachePut:用來更新緩存,用它來注解的方法都會被執行,執行完后結果被添加到緩存中。該方法不能和@Cacheable同時在同一個方法上使用。
6.對於@Caching注解來講,如果有兩種不同的需求,都是放在同一個方法上,這種需求如果只是使用@CacheEvict或者@CachePut是無法實現,因為他們不能多樣化的作用在同一個方法上。可以使用@Caching(evict={@CacheEvict(“a1”),@CacheEvict(“a2”,allEntries=true)});@Caching源代碼如下:
7.下面我們來看看CacheManager這個接口,源代碼如下:
不難看出,最終目的還是用來獲取Cache這個對象的,而我們緩存的數據都放在Cache中,部分源代碼如下:
8.上面的一些基本的東西都已說完,下面看看怎么配置,讓緩存真正的起作用:
來看看官方文檔給的寫法,里面重要的是spring-cache.xsd
其中的注解添加完,你就可以中代碼中使用了:
在使用spring中緩存時,我們一般選擇SimpleCacheManager這個類。
SimpleCacheManager源代碼如下:
可以看出我們需要配置caches這個屬性,來看看官方文檔的例子吧,在xml中添加如下代碼:創建了兩個緩存的名稱一個是books 一個是 default,我們可以只創建一個。
但是set中我們因該怎么寫,在文章開頭我們提到了ConcurrentMap這個類,再看下下面的紅框中,我們選擇一個,其中看其源代碼可知道ConcurrentMapCacheFactoryBean內容包含其他兩個。所有我們選擇這個。
其源代碼如下:
9.現在基本的配置都完成,現在就需要配置自己的bean去做下測試了。
編寫一個邏輯處理的類,把該類放在xml定義:
public class TestCacheService { //通過參數name @Cacheable(cacheNames="uCache",key="#name") public User get(String name){ User u = new User(); u.setAge(12); u.setUserName("jobs"); System.out.println("沒有緩存"+name); return u; } //通過方法名 @Cacheable(value="uCache",key="#root.methodName") public User get2(){ User u = new User(); u.setAge(12); u.setUserName("gate"); System.out.println("沒有緩存"); return u; } }
編寫一個測試類
public class TestCache { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("config/spring-cache.xml"); TestCacheService testCache = (TestCacheService)context.getBean("testCache"); testCache.get("jobs"); testCache.get("jobs");
}
}
運行測試一下,會發現報錯,原因是xml中的p:name沒有綁定:
在xml中添加:xmlns:p="http://www.springframework.org/schema/p"就可。
測試結果只有一行被打印處理,說明我們的緩存起作用了。
10.如何從緩存中提取緩存的數據:
首先我們要知道怎么從緩存中提取已經緩存過的數據:
public class TestCache { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("config/spring-cache.xml"); TestCacheService testCache = (TestCacheService)context.getBean("testCache"); CacheManager cm = (CacheManager) context.getBean("cacheManager"); //添加數據到緩存中 testCache.get("job"); Cache uCache = cm.getCache("uCache"); //通過參數作為key,得到對應的value User u1 = (User) uCache.get("job").get(); u1.show(); //添加數據到緩存中 testCache.get2(); //通過方法名作為key,得到對應value User u2 = (User) uCache.get("get2").get(); u2.show(); } }
當然還有其他形式作為其key,類如官方文檔就給了如下參考,它是使用spel:
當讓還有其它的緩存技術,例如ehcache,guava,jcache:
這個是我例子中用到的源代碼:spring緩存技術Caching例子