咱們知道一個程序的瓶頸在於數據庫,咱們也知道內存的速度是大大快於硬盤的速度的。當咱們須要重複地獲取相同的數據的時候,咱們一次又一次的請求數據庫或者遠程服務,致使大量的時間耗費在數據庫查詢或者遠程方法調用上,致使程序性能的惡化,這即是數據緩存要解決的問題。java
Spring定義了org.springframework.cache.CacheManager和org.springframework.cache.Cache接口用來統一不一樣的緩存的技術。其中,CacheManager是Spring提供的各類緩存技術抽象接口,Cache接口包含緩存的各類操做(增長、刪除、得到緩存,咱們通常不會直接和此接口打交道)。git
針對不一樣的緩存技術,須要實現不一樣的CacheManager,Spring定義瞭如表所示的CacheManager實現。 CacheManager|描述 ---|--- SimpleCacheManager|使用簡單的Collection來存儲緩存,主要用來測試 ConcurrentMapCacheManager|使用ConcurrentMap來存儲緩存 NoOpCacheManager|僅測試用,不會實際存儲緩存 EhCacheCacheManager|使用EhCache做爲緩存技術 GuavaCacheManager|使用google guava的GuavaCache做爲緩存技術(在1.5版本棄用了) HazelcastCacheManager|使用Hazelcast做爲緩存技術 JCacheCacheManager|支持JCache(JSR-107)標準的實現做爲緩存技術,如Apache Commons JCS RedisCacheManager|使用redis來做爲緩存技術github
在咱們使用任意一個實現的CacheManager的時候,需註冊實現的CacheManager的Bean,例如:redis
@Bean public EhCacheCacheManager cacheManager(CacheManager ehCacheCacheManager) { return new EhCacheCacheManager(ehCacheCacheManager); }
固然,每種緩存技術都有不少的額外配置,但配置cacheManager是必不可少的。spring
Spring提供了4個註解來聲明緩存規則(又是使用註解式的AOP的一個生動例子)。這四個註解如表所示。數據庫
註解 | 解釋 |
---|---|
@Cacheable | 在方法執行前,Spring先檢查緩存中是否有數據,若是有數據就直接返回緩存中的數據;若是沒有就調用方法,並將返回值放入緩存。 |
@CachePut | 不管怎麼樣,都會將方法的返回值放到緩存中。@CachePut的屬性和@Cacheable保持一致 |
@CacheEvict | 將一條或多條數據從緩存中刪除 |
@Caching | 能夠經過該註解,組合多個註解策略在一個方法上 |
@Cacheable、@CachePut、@CacheEvit都有value屬性,指定的是要使用的緩存名稱;key屬性指定的是數據在緩存中的存儲的鍵。express
開啓聲名式緩存支持十分簡單,只需在配置類上使用@EnableCaching註解便可,例如:apache
@Configuration @EnableCaching public class AppConfig { }
在Spring中使用緩存技術的關鍵是配置CacheManager,而Spring Boot爲咱們自動配置了多個CacheManager的實現。 Spring Boot的CacheManager的自動配置放置在org.springframework.boot.autoconfigure.cache包中,如圖所示。緩存
經過圖咱們能夠看出,Spring Boot爲咱們自動配置了EhCacheCacheConfiguration(使用EhCache)、GenericCacheConfiguration(使用Collection)、GuavaCacheConfiguration(使用Guava)、HazelcastCacheConfiguration(使用Hazelcast)、InfinispanCacheConfiguration(使用Infinispan)、JCacheCacheConfiguration(使用JCache)、NoOpCacheConfiguration(不使用存儲)、RedisCacheConfiguration(使用Redis)、SimpleCacheConfiguration(使用ConcurrentMap)。在不作任何額外配置的狀況下,默認使用的是SimpleCacheConfiguration,即便用ConcurrentMapCacheManager。app
/* * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.boot.autoconfigure.cache; import java.util.List; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cache.CacheManager; import org.springframework.cache.concurrent.ConcurrentMapCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; /** * Simplest cache configuration, usually used as a fallback. * * @author Stephane Nicoll * @since 1.3.0 */ @Configuration @ConditionalOnMissingBean(CacheManager.class) @Conditional(CacheCondition.class) class SimpleCacheConfiguration { private final CacheProperties cacheProperties; private final CacheManagerCustomizers customizerInvoker; SimpleCacheConfiguration(CacheProperties cacheProperties, CacheManagerCustomizers customizerInvoker) { this.cacheProperties = cacheProperties; this.customizerInvoker = customizerInvoker; } @Bean // 默認使用ConcurrentMapCacheManager public ConcurrentMapCacheManager cacheManager() { ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(); List<String> cacheNames = this.cacheProperties.getCacheNames(); if (!cacheNames.isEmpty()) { cacheManager.setCacheNames(cacheNames); } return this.customizerInvoker.customize(cacheManager); } }
Spring Boot支持以「spring.cache」爲前綴的屬性來配置緩存。
spring.cache.type= # 可選generic, ehcache, hazelcast, infinispan, jcache, redis, guava, simple, none spring.cache.cache-names= # 程序啓動時建立緩存名稱 spring.cache.ehcache.config= # ehcache配置文件地址 spring.cache.hazelcast.config= # hazelcast 配置文件地址 spring.cache.infinispan.config= # infinispan 配置文件地址 spring.cache.jcache.config= # jcache 配置文件地址 spring.cache.jcache.provider= #當多個 jcache實如今類路徑中的時候,指定jcache實現 spring.cache.guava.spec= # guava specs
在Spring Boot環境下,使用緩存技術只需在項目中導入相關緩存技術的依賴包,並在配置類使用@EnableCaching開啓緩存支持便可。
爲監控而生的多級緩存框架 layering-cache這是我開源的一個多級緩存框架的實現,若是有興趣能夠看一下