慢來比較快,虛心學技術
緩存( Caching )可以存儲經常會用到的信息,這樣每次需要的時候,這些信息都是立即可用的。我們將會瞭解到 Spring 的緩存抽象。儘管 Spring 自身並沒有實現緩存解決方案,但是它對緩存功能提供了聲明式的支持,能夠與多種流行的緩存實現進行集成
Ⅰ、開啓緩存支持
- 註解開啓:@EnableCaching
- 配置開啓: <cache:annotation-driven>
兩種開啓方法的工作方式是相同的。它們都會創建一個切面( aspect )並觸發Spring 緩存註解的切點( pointcut )。根據所使用的註解以及緩存的狀態,這個切面會從緩存中獲取數據,將數據添加到緩存之中或者從緩存中移除某個值。
import org.springframework.cache.annotation.EnableCaching;
@Configuration
@EnableCaching
public class CacheConfig {
}
<?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-manager屬性用來指定當前所使用的CacheManager對應的bean的名稱,默認是cacheManager-->
<cache:annotation-driven/>
</beans>
Ⅱ、配置緩存管理器
緩存管理器:是 Spring 緩存抽象的核心,它能夠與多個流行的緩存實現進行集成
Spring內置了多個緩存管理器:
- SimpleCacheManager
- NoOpCacheManager
- ConcurrentMapCacheManager----------默認使用的緩存管理器
- CompositeCacheManager
- EhCacheCacheManager-------------------較常用
- RedisCacheManager (來自於 Spring Data Redis 項目)-----------------較常用
- GemfireCacheManager (來自於 Spring Data GemFire 項目)
1、配置ConcurrentMapCacheManager
①註解配置
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching
public class ConcurrentMapCacheConfig {
@Bean
public CacheManager cacheManager1(){
return new ConcurrentMapCacheManager();
}
}
②XML配置
<?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/>
<!--定義緩存管理器-->
<bean id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager">
</bean>
</beans>
2、配置EhCacheCacheManager
EhCache 是一個純Java的進程內緩存框架,具有快速、精幹等特點,是Hibernate中默認的CacheProvider
緩存數據有三級:內存、堆外緩存Off-Heap、Disk緩存,因此無需擔心容量問題。還可以通過RMI、可插入API等方式進行分佈式緩存。
緩存數據會在虛擬機重啓的過程中寫入磁盤,持久化。
具有緩存和緩存管理器的偵聽接口。
支持多緩存管理器實例,以及一個實例的多個緩存區域。
由於Spring只是提供了基本的管理器接口,還需要依賴於ehcache的第三方cache實現管理
引入依賴:
<!-- 引入Spring對cache的支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework.version}</version>
<scope>compile</scope>
</dependency>
<!-- 引入ecache支持 -->
<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.3</version>
</dependency>
①註解配置,此處使用的CacheManager是ehcache的緩存管理器
import net.sf.ehcache.CacheManager;
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;
@Configuration
@EnableCaching
public class EhCacheConfig {
/**
* 定義緩存管理器,EhCacheCacheManager是Spring提供的管理器支持,需要將ecache的緩存管理器注入到EhCacheCacheManager中
**/
@Bean
public EhCacheCacheManager cacheManager2(CacheManager cm){
return new EhCacheCacheManager(cm);
}
/**
* 定義緩存管理器工廠,用於生產EhCacheManager
**/
@Bean
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){
EhCacheManagerFactoryBean factoryBean = new EhCacheManagerFactoryBean();
factoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
return factoryBean;
}
}
②XML配置
<?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/>
<!--定義緩存管理器-->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehcache"></property>
</bean>
<!--定義緩存管理器工廠-->
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath*:ehcache.xml"></property>
</bean>
</beans>
其中,ehcache.xml配置文件簡單配置如下:
<ehcache>
<diskStore path="java.io.tmpdir"/>
<!--
maxElementsOnDisk:磁盤緩存中最多可以存放的元素數量,0表示無窮大
maxElementsInMemory:內存緩存中最多可以存放的元素數量,若放入Cache中的元素超過這個數值,則有以下兩種情況
1)若overflowToDisk=true,則會將Cache中多出的元素放入磁盤文件中
2)若overflowToDisk=false,則根據memoryStoreEvictionPolicy策略替換Cache中原有的元素
eternal:緩存中對象是否永久有效,即是否永駐內存,true時將忽略timeToIdleSeconds和timeToLiveSeconds
timeToIdleSeconds:緩存數據在失效前的允許閒置時間(單位:秒),僅當eternal=false時使用,默認值是0表示可閒置時間無窮大,此爲可選屬性
即訪問這個cache中元素的最大間隔時間,若超過這個時間沒有訪問此Cache中的某個元素,那麼此元素將被從Cache中清除
timeToLiveSeconds:緩存數據在失效前的允許存活時間(單位:秒),僅當eternal=false時使用,默認值是0表示可存活時間無窮大
即Cache中的某元素從創建到清楚的生存時間,也就是說從創建開始計時,當超過這個時間時,此元素將從Cache中清除
overflowToDisk:內存不足時,是否啓用磁盤緩存(即內存中對象數量達到maxElementsInMemory時,Ehcache會將對象寫到磁盤中)
會根據標籤中path值查找對應的屬性值,寫入磁盤的文件會放在path文件夾下,文件的名稱是cache的名稱,後綴名是data
diskPersistent:是否持久化磁盤緩存,當這個屬性的值爲true時,系統在初始化時會在磁盤中查找文件名爲cache名稱,後綴名爲index的文件
這個文件中存放了已經持久化在磁盤中的cache的index,找到後會把cache加載到內存
要想把cache真正持久化到磁盤,寫程序時注意執行net.sf.ehcache.Cache.put(Element element)後要調用flush()方法
-->
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"/>
<!--定義一個緩存-->
<cache name="ehCache"
maxElementsOnDisk="20000"
maxElementsInMemory="2000"
eternal="false"
overflowToDisk="true"
diskPersistent="true"/>
</ehcache>
3、配置RedisCacheManager
Redis 可以用來爲 Spring 緩存抽象機制存儲緩存條目, Spring Data Redis 提供了 RedisCacheManager ,這是 CacheManager 的一個實現。
RedisCacheManager 會與一個 Redis 服務器協作,並通過 RedisTemplate 將緩存條目存儲到 Redis 中
上一節已經瞭解過Redis,此處我們需要先引入Redis支持:
<!--引入Spring Data Redis-->
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
<!--引入jedis支持-->
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.1</version>
</dependency>
①混合配置
application-redis.xml
<?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"
xmlns:context="http://www.springframework.org/schema/context"
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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<cache:annotation-driven cache-manager="redisCacheManager"/>
</beans>
RedisConfig.java
@Configuration
@ComponentScan(basePackages = {"com.my.spring.dao"})
@ImportResource("classpath:application-redis.xml")//引入配置文件
@EnableCaching
public class RedisCacheConfig {
/**
* 定義緩存管理器,注入redisConnectionFactory
* @param redisConnectionFactory
* @return
*/
@Bean("redisCacheManager")
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory){
RedisCacheManager.RedisCacheManagerBuilder builder =
RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory);
Set<String> cacheNames = new HashSet<String>() {{
add("myCache");
}};
//設置多個緩存
builder.initialCacheNames(cacheNames);
return builder.build();
}
/**
* 定義Redis連接工廠
* @return
*/
@Bean
public JedisConnectionFactory redisConnectionFactory(){
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.afterPropertiesSet();
return factory;
}
}
四、混合使用多種緩存CompositeCacheManager
我們並不是只能有且僅有一個緩存管理器。如果你很難確定該使用哪個緩存管理器,或者有合法的技術理由使用超過一個緩存管理器的話,那麼可以嘗試使用 Spring 的 CompositeCacheManager.CompositeCacheManager 要通過一個或更多的緩存管理器來進行配置,它會迭代這些緩存管理器,以查找之前所緩存的值