SpringBoot - 默认缓存配置以及运行流程
2018-05-30 本文已影响8人
BzCoder
今天来学习下SpringBoot中的缓存。
一.HelloWorld
在SpringBoot开启缓存功能非常简单,只需要三步,就可以了,我们可以通过是否输出文字来判断程序是否查询了数据库。
- 引入MAVEN
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
- 增加配置注解@EnableCaching
@SpringBootApplication
@EnableCaching
public class CacheApplication {
public static void main(String[] args) {
SpringApplication.run(CacheApplication.class, args);
}
}
- 增加缓存注解 @Cacheable
package com.example.cache.service;
import com.example.cache.bean.Employee;
import com.example.cache.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
* @author BaoZhou
* @date 2018/5/29
*/
@Service
public class EmployeeService {
@Autowired
private EmployeeMapper mapper;
@Cacheable(cacheNames = {"empCache"} )
public Employee getEmp(Integer id) {
System.out.println("查询了查询了");
return mapper.getEmpById(id);
}
}
二.SpringBoot默认缓存配置原理
说到原理,我们就又要看自动配置文件了。打开CacheAutoConfiguration类。
/**
* {@link EnableAutoConfiguration Auto-configuration} for the cache abstraction. Creates a
* {@link CacheManager} if necessary when caching is enabled via {@link EnableCaching}.
* <p>
* Cache store can be auto-detected or specified explicitly via configuration.
*
* @author Stephane Nicoll
* @since 1.3.0
* @see EnableCaching
*/
@Configuration
@ConditionalOnClass(CacheManager.class)
@ConditionalOnBean(CacheAspectSupport.class)
@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")
@EnableConfigurationProperties(CacheProperties.class)
@AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
@AutoConfigureAfter({ CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class,
RedisAutoConfiguration.class })
@Import(CacheConfigurationImportSelector.class)
public class CacheAutoConfiguration {
...
}
从头部注释可以看到,我们需要用@EnableCaching让自动配置类生效。 接下来我们看CacheConfigurationImportSelector.class,从命名上可以了解,这是引入不同的缓存配置类的选择器,打上断点发现容器中包含各种缓存的配置。
0 = "org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration"
1 = "org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration"
2 = "org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration"
3 = "org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration"
4 = "org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration"
5 = "org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration"
6 = "org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration"
7 = "org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration"
8 = "org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration"
9 = "org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration"
我们打开DEBUG后运行后,在LOG中我们可以看到SimpleCacheConfiguration matched,所以当不配置时默认选择的是SimpleCacheConfiguration。
![](https://img.haomeiwen.com/i11197254/66163c0eebeb1826.png)
SimpleCacheConfiguration向容器中添加一个cacheManager。
@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
public ConcurrentMapCacheManager cacheManager() {
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
cacheManager.setCacheNames(cacheNames);
}
return this.customizerInvoker.customize(cacheManager);
}
}
而cacheManager是一个ConcurrentMapCacheManager类型的,其中包含了cache的基本操作,默认是使用ConcurrentHashMap来管理缓存。
@Override
@Nullable
public Cache getCache(String name) {
Cache cache = this.cacheMap.get(name);
if (cache == null && this.dynamic) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(name);
if (cache == null) {
cache = createConcurrentMapCache(name);
this.cacheMap.put(name, cache);
}
}
}
return cache;
}
而KEY的生成默认使用SimpleKeyGenerator。
/**
* Generate a key based on the specified parameters.
*/
public static Object generateKey(Object... params) {
if (params.length == 0) {
return SimpleKey.EMPTY;
}
if (params.length == 1) {
Object param = params[0];
if (param != null && !param.getClass().isArray()) {
return param;
}
}
return new SimpleKey(params);
}
SimpleKeyGenerator是在CacheAspectSupport中定义的。CacheInterceptor是CacheAspectSupport的实现类。而CacheInterceptor最终是在CacheProxyFactoryBean中定义的。CacheProxyFactoryBean应该是在SpringBoot配置中已经注入。
那么有关于SpringBoot默认缓存配置以及运行流程就讲到这里。