SpringBoot系列(7)---SpringBoot-Cache(EhCache)

SpringBoot提供数据缓存的功能,相信非常多人已经用过cache了。因为数据库的IO瓶颈应该大家也吃过不少亏了,所以一般情况下我们都会引入非常多的缓存策略,例如引入redis,引入hibernate的二级缓存等等。

SpringBoot在annotation的层面给我们实现了cache,当然这也是得益于Spring的AOP。所有的缓存配置只是在annotation层面配置,完全没有侵入到我们的代码当中,就像我们的声明式事务一样。

Spring定义了CacheManager和Cache接口统一不同的缓存技术。其中CacheManager是Spring提供的各种缓存技术的抽象接口。而Cache接口包含缓存的各种操作,当然我们一般情况下不会直接操作Cache接口。


Spring针对不同的缓存技术,需要实现不同的cacheManager,Spring定义了如下的cacheManger实现

CacheManger 描述
SimpleCacheManager 使用简单的Collection来存储缓存,主要用于测试
ConcurrentMapCacheManager 使用ConcurrentMap作为缓存技术(默认)
NoOpCacheManager 测试用
EhCacheCacheManager 使用EhCache作为缓存技术,以前在hibernate的时候经常用
GuavaCacheManager 使用google guava的GuavaCache作为缓存技术
HazelcastCacheManager 使用Hazelcast作为缓存技术
JCacheCacheManager 使用JCache标准的实现作为缓存技术,如Apache Commons JCS
RedisCacheManager 使用Redis作为缓存技术

当然常规的SpringBoot已经为我们自动配置了EhCache、Collection、Guava、ConcurrentMap等缓存,默认使用SimpleCacheConfiguration,即使用ConcurrentMapCacheManager。SpringBoot的application.properties配置文件,使用spring.cache前缀的属性进行配置。

spring.cache.type=#缓存的技术类型
spring.cache.cache-names=应用程序启动创建缓存的名称
spring.cache.ehcache.config=ehcache的配置文件位置
spring.cache.infinispan.config=infinispan的配置文件位置
spring.cache.jcache.config=jcache配置文件位置
spring.cache.jcache.provider=当多个jcache实现类时,指定选择jcache的实现类

在SpringBoot环境下我们需要导入相关缓存技术的依赖,并在配置类当中配置@EnableCaching开启缓存技术。

我们这里不适用默认的ConcurrentMapCache 而是使用 EhCache

所以我在resources目录下创建了ehcache.xml的配置文件,然后在application.properties 设置type为ehcache(intellij有明确的提示):

ehcache.xml:

 
  

    
    path="java.io.tmpdir"/>

    
    
    name="weibo" maxElementsInMemory="10000" />
 
    
                maxElementsInMemory="10000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="10"
            timeToLiveSeconds="120"
            diskPersistent="false"
            memoryStoreEvictionPolicy="LRU"
            diskExpiryThreadIntervalSeconds="120"/>

    
    
    
    
    
    
    

    

    

    


application.properties:

spring.cache.type=ehcache
spring.cache.ehcache.config=ehcache.xml
在配置类配置@EnableCaching

@SpringBootApplication
@EnableCaching
public class DemoApplication extends WebMvcConfigurerAdapter {

然后说说4个annotation的配置:

@Cacheable  在方法执行前Spring先是否有缓存数据,如果有直接返回。如果没有数据,调用方法并将方法返回值存放在缓存当中。

@CachePut   无论怎样,都将方法的范湖值放到缓存当中。

@CacheEvict   将一条或者多条数据从缓存中删除。

@Caching  可以通过@Caching注解组合多个注解集合在一个方法上


使用演示JPA时候的方法进行缓存测试:

@Transactional
@CachePut(value = "weibo",key="#weibo.weiboId")
public Weibo saveWeibo(Weibo weibo){
    this.weiboRepository.save(weibo);
    return weibo;
}

@Cacheable(value = "weibo")
public Weibo getWeiboById(long id){
    return this.weiboRepository.getByWeiboId(id);
}


@Transactional
@CacheEvict(value = "weibo",key = "#weibo.weiboId")
public void remove(Weibo weibo){
    this.weiboRepository.delete(weibo);
}


当然如果我们想单独配置一下weibo这个缓存可以通过ehcache.xml进行单独配置,不过需要提醒的是 maxElementsInMemory属性配置是必须的,否则无法启动SpringBoot应用。

name="weibo" maxElementsInMemory="10000" overflowToDisk="false" timeToIdleSeconds="60"  timeToLiveSeconds="120" />

通过Controller进行测试,缓存生效:

@RestController
@RequestMapping("/cache")
public class CacheTestController {

    @Autowired
    private WeiboService weiboService;
    @Autowired
    private UserRepository userRepository;

    @RequestMapping("/getWeibo/{id}")
    public Weibo getWeibo(@PathVariable("id") long id){
        return weiboService.getWeiboById(id);
    }

    @RequestMapping("/addWeibo")
    public Weibo addWeibo(String username,String weiboText){
        User user = userRepository.getByUsernameIs(username);
        Weibo weibo = new Weibo(user,weiboText,new Date(System.currentTimeMillis()));
        return this.weiboService.saveWeibo(weibo);
    }

    @RequestMapping("/delete/{id}")
    public Weibo delete(@PathVariable("id") long id){
        Weibo weibo = this.weiboService.getWeiboById(id);
        this.weiboService.remove(weibo);
        return weibo;
    }
}


你可能感兴趣的:(Spring,SpringBoot)