赞
踩
缓存技术主要分为两大类缓存可分为2大类:
Spring Boot提供了对多种本地缓存技术的支持,例如Caffeine、Ehcache、Guava等。本地缓存技术常用于提高应用程序的性能,避免频繁地访问数据库或其他外部资源,同时也可以降低系统的负载。JSR是Java Specification Requests 的缩写 ,Java规范请求,故名思议提交Java规范, JSR-107呢就是关于如何使用缓存的规范,是java提供的一个接口规范,类似于JDBC规范,没有具体的实现,具体的实现就是reds等这些缓存。
Java Caching(JSR-107)定义了5个核心接口,分别是CachingProvider、CacheManager、Cache、Entry和Expiry。
一个应用里面可以有多个缓存提供者(CachingProvider),一个缓存提供者可以获取到多个缓存管理器(CacheManager),一个缓存管理器管理着不同的缓存(Cache),缓存中是一个个的缓存键值对(Entry),每个entry都有一个有效期(Expiry)。缓存管理器和缓存之间的关系有点类似于数据库中连接池和连接的关系。
使用JSR107需要导入依赖:
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术,并支持使用JCache(JSR-107)注解来简化缓存开发
在启动类上使用@EnableCaching注解开启缓存
package com.sunxiaping.springboot; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; @SpringBootApplication @MapperScan(basePackages = "com.sunxiaping.springboot.mapper") @EnableCaching public class SpringbootApplication { public static void main(String[] args) { SpringApplication.run(SpringbootApplication.class, args); } }
使用@Cacheable注解方法返回的结果缓存:
package com.sunxiaping.springboot.service.impl; import com.sunxiaping.springboot.domain.Employee; import com.sunxiaping.springboot.mapper.EmployeeMapper; import com.sunxiaping.springboot.service.EmployeeService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Optional; /** * @author 许威威 * @version 1.0 */ @Service @Transactional public class EmployeeServiceImpl implements EmployeeService { @Autowired private EmployeeMapper employeeMapper; /** * @Cacheable注解: 将方法的运行结果进行缓存,以后再要相同的数据,直接从缓存中获取,不需要再调用方法 * CacheManager管理多个Cache组件,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件都有自己唯一的名称 * @Cacheable注解的属性: * value/cacheNames:指定缓存组件的名称 * key:缓存数据使用的key,默认是方法参数的值(如果传入的参数是1,那么值就是1对应的返回的返回值。),支持SPEL表达式。 * keyGenerator:key的生成器,可以自己指定key的生成器的组件id。key和keyGenerator二选一。 * cacheManager:指定缓存管理器。 * cacheResolver:指定缓存解析器。 * condition:指定符合条件的情况下才缓存。支持SPEL表达式。 * unless:否定缓存。当unless指定的条件为true,方法的返回值就不会返回。 * sync:是否同步,默认值是false,即异步,在多线程环境中需要设置为true,避免缓存击穿的问题。 */ @Cacheable(cacheNames = "emp", key = "#id") @Override public Employee findEmpById(Integer id) { return Optional.ofNullable(employeeMapper.findEmpById(id)).orElse(new Employee()); } }
@AutoConfiguration(after = { CouchbaseDataAutoConfiguration.class, HazelcastAutoConfiguration.class, HibernateJpaAutoConfiguration.class, RedisAutoConfiguration.class }) @ConditionalOnClass(CacheManager.class) @ConditionalOnBean(CacheAspectSupport.class) @ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver") @EnableConfigurationProperties(CacheProperties.class) //这个注解给可以知道其向Spring容器中导入了一些组件 @Import({ CacheConfigurationImportSelector.class, CacheManagerEntityManagerFactoryDependsOnPostProcessor.class }) public class CacheAutoConfiguration { @Bean @ConditionalOnMissingBean public CacheManagerCustomizers cacheManagerCustomizers(ObjectProvider<CacheManagerCustomizer<?>> customizers) { return new CacheManagerCustomizers(customizers.orderedStream().collect(Collectors.toList())); } @Bean public CacheManagerValidator cacheAutoConfigurationValidator(CacheProperties cacheProperties, ObjectProvider<CacheManager> cacheManager) { return new CacheManagerValidator(cacheProperties, cacheManager); } @ConditionalOnClass(LocalContainerEntityManagerFactoryBean.class) @ConditionalOnBean(AbstractEntityManagerFactoryBean.class) static class CacheManagerEntityManagerFactoryDependsOnPostProcessor extends EntityManagerFactoryDependsOnPostProcessor { CacheManagerEntityManagerFactoryDependsOnPostProcessor() { super("cacheManager"); } }
通过CacheAutoConfiguration上面的@Import注解,可以知道其向Spring容器中导入了一些组件,dubug后的缓存配置类如下所示
@Configuration(proxyBeanMethods = false) @ConditionalOnMissingBean(CacheManager.class) @Conditional(CacheCondition.class) class SimpleCacheConfiguration { //给容器中添加了ConcurrentMapCacheManager组件 @Bean ConcurrentMapCacheManager cacheManager(CacheProperties cacheProperties, CacheManagerCustomizers cacheManagerCustomizers) { ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(); List<String> cacheNames = cacheProperties.getCacheNames(); if (!cacheNames.isEmpty()) { cacheManager.setCacheNames(cacheNames); } return cacheManagerCustomizers.customize(cacheManager); } }
public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderAware { //重写CacheManager的getCache方法 @Override @Nullable public Cache getCache(String name) { //根据传入的name从CacheManager中获取Cache对象 Cache cache = this.cacheMap.get(name); //如果cache不存在 if (cache == null && this.dynamic) { //加锁 synchronized (this.cacheMap) { //再获取一次 cache = this.cacheMap.get(name); //如果依然不遵从 if (cache == null) { //创建一个新的ConcurrentMapCache并返回 cache = createConcurrentMapCache(name); //将上面创建的ConcurrentMapCache作为value放入到CacheManager中,key就是传入的name this.cacheMap.put(name, cache); } } } return cache; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。