20191127 Spring Boot官方文档学习(4.12)
4.12。缓存(Caching)
Spring框架提供了对应用程序透明添加缓存的支持。从本质上讲,抽象将缓存应用于方法,从而根据缓存中可用的信息减少执行次数。缓存逻辑是透明应用的,不会对调用者造成任何干扰。只要通过@EnableCaching
注解启用了缓存支持,Spring Boot就会自动配置缓存基础结构。
简而言之,将缓存添加到服务的操作就像将相关注解添加到其方法一样容易,如以下示例所示:
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
@Component
public class MathService {
@Cacheable("piDecimals")
public int computePiDecimal(int i) {
// ...
}
}
本示例说明了在潜在的昂贵操作上使用缓存的方法。在调用computePiDecimal
之前,抽象将在piDecimals
高速缓存中寻找与i参数匹配的条目。如果找到条目,则高速缓存中的内容会立即返回给调用方,并且不会调用该方法。否则,将调用该方法,并在返回值之前更新缓存。
您还可以透明地使用标准JSR-107
(JCache
)注解(例如@CacheResult
)。但是,我们强烈建议您不要混合使用Spring Cache和JCache注解。
如果您不添加任何特定的缓存库,Spring Boot会自动配置一个使用内存中并发map的简单提供程序。当需要缓存时(例如前面的示例piDecimals),此提供程序将为您创建它。实际上,不建议将简单的提供程序用于生产用途,但是它对于入门并确保您了解功能非常有用。确定要使用的缓存提供程序后,请确保阅读其文档,以了解如何配置应用程序使用的缓存。几乎所有提供程序都要求您显式配置在应用程序中使用的每个缓存。有些提供了通过spring.cache.cache-names
属性定制默认缓存。
还可以透明地从缓存中更新或删除数据。
更多信息参考Spring Framework的文档
4.12.1。支持的缓存提供程序
缓存抽象不提供实际的存储,而是依赖于org.springframework.cache.Cache和org.springframework.cache.CacheManager
接口实现的抽象。
如果尚未定义类型为CacheManager
或CacheResolver
且名称为cacheResolver
的bean (请参阅CachingConfigurer
),Spring Boot会尝试检测以下提供程序(按指示的顺序,参考org.springframework.boot.autoconfigure.cache.CacheType
):
- Generic
- JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
- EhCache 2.x
- Hazelcast
- Infinispan
- Couchbase
- Redis
- Caffeine
- Simple
- None
可以通过设置spring.cache.type
属性来强制使用特定的缓存提供程序。如果您需要在某些环境(例如测试)中完全禁用缓存,请使用此属性。
使用spring-boot-starter-cache
启动器快速添加基本的缓存依赖项。启动器带进来spring-context-support
。如果手动添加依赖项,则必须包括spring-context-support
才能使用JCache
,EhCache 2.x
或Caffeine
支持。
如果Spring Boot自动配置了CacheManager
,您可以通过公开实现CacheManagerCustomizer
接口的bean,在完全初始化之前进一步调整其配置。下面的示例设置一个标志,指示应将null
值向下传递到底层的Map:
@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
@Override
public void customize(ConcurrentMapCacheManager cacheManager) {
cacheManager.setAllowNullValues(false);
}
};
}
在前面的示例中,需要进行自动配置的ConcurrentMapCacheManager
。如果不是这种情况(您提供了自己的配置,或者自动配置了其他缓存提供程序),则根本不会调用定制程序。您可以根据需要拥有任意数量的定制程序,也可以使用@Order
或Ordered
对其进行排序。
Generic
如果上下文定义了至少一个org.springframework.cache.Cache
bean,则使用通用缓存。CacheManager
将包装所有该类型的bean。
JCache(JSR-107)
JCache通过类路径上的javax.cache.spi.CachingProvider
进行引导(即,类路径上存在符合JSR-107的缓存库),并且JCacheCacheManager
由spring-boot-starter-cache
“启动器”提供。各种兼容的库可用,Spring Boot为Ehcache 3
,Hazelcast
和Infinispan
提供了依赖管理。也可以添加任何其他兼容的库。
可能会出现多个提供者,在这种情况下,必须明确指定提供者。即使JSR-107标准没有强制采用标准化的方式来定义配置文件的位置,Spring Boot也会尽其最大努力来容纳具有实现细节的缓存,如以下示例所示:
# Only necessary if more than one provider is present
spring.cache.jcache.provider=com.acme.MyCachingProvider
spring.cache.jcache.config=classpath:acme.xml
当缓存库同时提供原生实现和JSR-107支持时,Spring Boot会首选JSR-107支持,因此,如果您切换到其他JSR-107实现,则可以使用相同的功能。
Spring Boot 对Hazelcast具有常规支持。如果单个HazelcastInstance
可用,则除非指定了spring.cache.jcache.config
属性,否则它也会自动重用于CacheManager
。
有两种方法可以自定义底层 javax.cache.cacheManager
:
- 可以在启动时通过设置
spring.cache.cache-names
属性来创建缓存。如果定义了定制javax.cache.configuration.Configuration
bean,则将其用于定制它们。 - 使用
CacheManager
的引用调用org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer
bean 进行完全定制。
如果定义了标准javax.cache.CacheManager
bean,它将自动包装在org.springframework.cache.CacheManager
抽象期望的实现中。不再对其应用定制。
EhCache 2.x
如果可以在类路径的根目录找到名为ehcache.xml
的文件,则使用EhCache2.x
。如果找到EhCache 2.x,则使用spring-boot-starter-cache
“启动器” 提供的EhCacheCacheManager
来引导缓存管理器。也可以提供备用配置文件,如以下示例所示:
spring.cache.ehcache.config=classpath:config/another-config.xml
Hazelcast
Spring Boot 对Hazelcast具有常规支持。如果已经自动配置了HazelcastInstance
,则会自动将其包装在CacheManager
中。
Infinispan
Infinispan没有默认配置文件位置,因此必须明确指定。否则,将使用默认的引导程序。
spring.cache.infinispan.config=infinispan.xml
可以在启动时通过设置spring.cache.cache-names
属性来创建缓存。如果定义了定制ConfigurationBuilder
bean,那么它将用于定制高速缓存。
Spring Boot对Infinispan的支持仅限于嵌入式模式,并且非常基础。如果您需要更多选择,则应该使用官方的Infinispan Spring Boot启动器。有关更多详细信息,请参见Infinispan的文档。
Couchbase
如果Couchbase Java客户端和couchbase-spring-cache
实现可用,并且已配置 Couchbase ,则会自动配置 CouchbaseCacheManager
。通过设置spring.cache.cache-names
属性,还可以在启动时创建其他缓存。这些缓存在自动配置的Bucket上运行。通过使用定制,您还可以在另一个Bucket中创建其他缓存。假设您在“main” Bucket上需要两个缓存(cache1和cache2),在“another” Bucket上需要一个2秒的自定义生存时间的缓存(cache3)。您可以通过配置创建前两个缓存,如下所示:
spring.cache.cache-names=cache1,cache2
然后,您可以定义一个@Configuration
类来配置额外的Bucket和cache3缓存,如下所示:
@Configuration(proxyBeanMethods = false)
public class CouchbaseCacheConfiguration {
private final Cluster cluster;
public CouchbaseCacheConfiguration(Cluster cluster) {
this.cluster = cluster;
}
@Bean
public Bucket anotherBucket() {
return this.cluster.openBucket("another", "secret");
}
@Bean
public CacheManagerCustomizer<CouchbaseCacheManager> cacheManagerCustomizer() {
return c -> {
c.prepareCache("cache3", CacheBuilder.newInstance(anotherBucket())
.withExpiration(2));
};
}
}
此样本配置重用了通过自动配置创建的Cluster。
Redis
如果Redis可用并已配置,则会自动配置RedisCacheManager
。可以通过设置spring.cache.cache-names
属性在启动时创建其他缓存,并且可以使用spring.cache.redis.*
属性配置缓存默认值。例如,以下配置创建cache1和cache2缓存的生存时间为 10分钟:
spring.cache.cache-names=cache1,cache2
spring.cache.redis.time-to-live=600000
默认情况下,会添加key前缀,这样,如果两个单独的缓存使用相同的密钥,则Redis不会有重叠的密钥,也不会返回无效值。如果您创建自己的RedisCacheManager
,我们强烈建议将此设置保持启用状态。
您可以通过添加自己的RedisCacheConfiguration
@Bean来完全控制配置。如果您要自定义序列化策略,这将很有用。
Caffeine
Caffeine是对Guava
缓存的Java 8重写,它取代了对Guava的支持。如果存在Caffeine,则CaffeineCacheManager
将自动配置(由spring-boot-starter-cache
启动器提供)。缓存可以在启动时通过设置spring.cache.cache-names
属性来创建,并且可以通过以下方式之一(按指示的顺序)进行自定义:
- 缓存规范由
spring.cache.caffeine.spec
定义 - 定义了一个
com.github.benmanes.caffeine.cache.CaffeineSpec
bean - 定义了一个
com.github.benmanes.caffeine.cache.Caffeine
bean
例如,以下配置创建cache1和cache2缓存最大大小为500,生存时间为 10分钟
spring.cache.cache-names=cache1,cache2
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s
如果定义了com.github.benmanes.caffeine.cache.CacheLoader
bean,它将自动与CaffeineCacheManager
关联。由于CacheLoader
将会与缓存管理器管理的所有缓存相关联,因此必须将其定义为CacheLoader<Object, Object>
。自动配置将忽略任何其他通用类型。
Simple
如果找不到其他提供者,则配置使用ConcurrentHashMap
作为缓存存储的简单实现。如果您的应用程序中不存在任何缓存库,则这是默认设置。默认情况下,将根据需要创建缓存,但是您可以通过设置cache-names
属性来限制可用缓存的列表。例如,如果只需要cache1和cache2缓存,则按cache-names如下所示设置属性:
spring.cache.cache-names=cache1,cache2
如果这样做,并且您的应用程序使用了未列出的缓存,那么当需要该缓存时,它将在运行时失败,但不会在启动时失败。这类似于使用未声明的缓存时“实际”缓存提供程序的行为。
None
当配置中存在@EnableCaching
时,也将期望使用合适的缓存配置。如果需要在某些环境中完全禁用缓存,请指定none
缓存类型使用无操作实现,如以下示例所示:
spring.cache.type=none
20191127 Spring Boot官方文档学习(4.12)的更多相关文章
- 20191127 Spring Boot官方文档学习(9.1-9.3)
9."使用方法"指南 9.1.Spring Boot应用程序 9.1.1.创建自己的FailureAnalyzer FailureAnalyzer被包装在FailureAnalys ...
- 20191106 Spring Boot官方文档学习(1-2)
学习内容相关信息 最新版本:2.2.0 CURRENT GA 官网地址 官方文档地址 单页版文档地址 代码生成网址 2.入门 Spring Boot的主要目标是: 为所有Spring开发提供更快且入门 ...
- 20191127 Spring Boot官方文档学习(4.10)
4.10.使用SQL数据库 从使用JdbcTemplate直接的JDBC访问到完整的"对象关系映射"技术(例如Hibernate),Spring框架为使用SQL数据库提供了广泛的支 ...
- 20191127 Spring Boot官方文档学习(4.11)
4.11.使用NoSQL技术 Spring Data提供了其他项目来帮助您访问各种NoSQL技术,包括: Redis MongoDB Neo4J Solr Elasticsearch Cassandr ...
- 20191127 Spring Boot官方文档学习(4.13)
4.13.Messaging Spring框架为与消息传递系统集成提供了广泛的支持,从使用JmsTemplate简化JMS API到完整的异步接收消息的基础结构.Spring AMQP为高级消息队列协 ...
- 20191127 Spring Boot官方文档学习(4.14-4.17)
4.14.使用RestTemplate调用REST服务 如果需要从应用程序调用远程REST服务,则可以使用Spring Framework的RestTemplate类.由于RestTemplate实例 ...
- 20191127 Spring Boot官方文档学习(4.18-4.24)
4.18.JTA的分布式事务 通过使用Atomikos或Bitronix嵌入式事务管理器,Spring Boot支持跨多个XA资源的分布式JTA事务.部署到合适的Java EE应用程序服务器时,还支持 ...
- 20191127 Spring Boot官方文档学习(4.25)
4.25. Testing Spring Boot提供了许多实用程序和注解,可以在测试应用程序时提供帮助.测试支持由两个模块提供:spring-boot-test包含核心项,spring-boot-t ...
- 20191127 Spring Boot官方文档学习(5)
5.Spring Boot Actuator:可投入生产的功能 Spring Boot包含许多其他功能,可帮助您在将应用程序投入生产时监控和管理您的应用程序.您可以选择使用HTTP端点或JMX管理和监 ...
随机推荐
- Berlekamp-Massey algorithm
https://www.cnblogs.com/zzqsblog/p/6877339.html https://blog.csdn.net/qq_39972971/article/details/80 ...
- HashMap的底层实现以及解决hash值冲突的方式
class HashMap<K,V> extends AbstractMap<K,V> HashMap put() HashMap get() 1.put() HashMa ...
- POJ-1904-King‘s Quest
链接: https://vjudge.net/problem/POJ-1904 题意: Once upon a time there lived a king and he had N sons. A ...
- 任意修改网页内容JS代码
浏览器输入框执行,chrome需要粘贴后,需要在前面手打javascript: 因为粘贴的会自动过滤 javascript:document.body.contentEditable='true'; ...
- Docker(五):Dockerfile
我们使用 Dockerfile 定义镜像,依赖镜像来运行容器,因此 Dockerfile 是镜像和容器的关键,Dockerfile 可以非常容易的定义镜像内容,同时在我们后期的微服务实践中,Docke ...
- 导入本地Excel到DataSet中
/// <summary> /// 导入本地Excel到DataSet中 /// </summary> /// <param name="strFileSour ...
- PHP+FLASH大文件断点续传功能分享
1.使用PHP的创始人 Rasmus Lerdorf 写的APC扩展模块来实现(http://pecl.php.net/package/apc) APC实现方法: 安装APC,参照官方文档安装,可以使 ...
- BZOJ 3193: [JLOI2013]地形生成 计数 + 组合 + 动态规划
第一问: 先不考虑山的高度有相同的:直接按照高度降序排序,试着将每一座山插入到前面山的缝隙中. 当然,这并不代表这些山的相对位置是固定的,因为后面高度更低的山是有机会插入进来的,所以就可以做到将所有情 ...
- JUnit——运行多个测试方法
TDD=Test Drive Development 在实际应用中作用特别大,因为我们会定义很多的类和方法,也会存在很多的更新操作,这样如果用main函数进行测试,则会异常麻烦. 而如果用这种多个 ...
- 联系人:ContactsContract类
Android系统管理联系人的URI如下: ContactsContract.Contacts.CONTENT_URI 管理联系 ...