-SpringBoot-Cache(EhCache)

本文介绍如何在Spring Boot中利用EhCache实现缓存功能,包括配置方式、使用注解进行缓存操作的方法及示例代码。
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:

<ehcache>
    <!-- 指定一个文件目录,当EHCache把数据写到硬盘上时,将把数据写到这个文件目录下 -->
    <diskStore path="java.io.tmpdir"/>

    <!-- 设定缓存的默认数据过期策略 -->
    
    <cache name="weibo" maxElementsInMemory="10000" />
 
    
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="10"
            timeToLiveSeconds="120"
            diskPersistent="false"
            memoryStoreEvictionPolicy="LRU"
            diskExpiryThreadIntervalSeconds="120"/>

    <!-- maxElementsInMemory 内存中最大缓存对象数,看着自己的heap大小来搞 -->
    <!-- eternal:true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false -->
    <!-- maxElementsOnDisk:硬盘中最大缓存对象数,若是0表示无穷大 -->
    <!-- overflowToDisk:true表示当内存缓存的对象数目达到了maxElementsInMemory界限后,
    会把溢出的对象写到硬盘缓存中。注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。-->
    <!-- diskSpoolBufferSizeMB:磁盘缓存区大小,默认为30MB。每个Cache都应该有自己的一个缓存区。-->
    <!-- diskPersistent:是否缓存虚拟机重启期数据  -->
    <!-- diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认为120秒 -->

    <!-- timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,
    如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,
    EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,
    则表示对象可以无限期地处于空闲状态 -->

    <!-- timeToLiveSeconds:设定对象允许存在于缓存中的最长时间,以秒为单位。当对象自从被存放到缓存中后,
    如果处于缓存中的时间超过了 timeToLiveSeconds属性值,这个对象就会过期,
    EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。如果该属性值为0,
    则表示对象可以无限期地存在于缓存中。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义 -->

    <!-- memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,
    Ehcache将会根据指定的策略去清理内存。可选策略有:LRU(最近最少使用,默认策略)、
    FIFO(先进先出)、LFU(最少访问次数)。-->

</ehcache>

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应用。

<cache 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;
    }
}


<think>好的,我现在需要帮助用户寻找在Spring Boot 3.3.7中替换EhCacheCache的替代方案。首先,我要回顾一下用户的问题。用户之前可能在使用EhCache,但由于某些原因需要替换,比如升级到Spring Boot 3.x后可能遇到兼容性问题,或者EhCache不再满足需求。 首先,我应该确认EhCache在Spring Boot 3.3.7中的支持情况。根据引用内容中的引用[3],Spring Boot升级到3.x需要迁移到Jakarta EE,这可能影响到依赖库的兼容性。EhCache的旧版本可能依赖于javax包,而Spring Boot 3.x使用jakarta包,这可能导致EhCache无法直接使用,需要升级到支持Jakarta的版本。但用户可能想换其他缓存方案,所以需要提供替代方案。 接下来,我需要列出常见的Spring Boot支持的缓存方案。通常,Spring Boot集成了多种缓存提供者,比如Caffeine、Redis、Hazelcast、Infinispan等。此外,引用[4]提到dynamic-datasource-spring-boot-starter,但那是多数据源的,可能和缓存无关,不过可以忽略这点,专注于缓存替代方案。 我需要检查每个替代方案的适用性: 1. **Caffeine**:这是一个高性能的Java缓存库,Spring Boot原生支持,配置简单,适合本地缓存,替代EhCache的好选择。 2. **Redis**:分布式缓存,适合需要跨多个实例共享缓存的场景,如果用户的应用是分布式的,Redis是个不错的选择。 3. **Hazelcast**:既是缓存解决方案,也提供分布式数据网格功能,可以作为内存数据网格使用。 4. **Infinispan**:开源分布式缓存和数据网格平台,适合需要高度可扩展性的场景。 5. **Spring Boot内置的SimpleCache**:适用于简单场景,但功能有限,可能不适合生产环境。 6. **检查EhCache 3.x的兼容性**:EhCache 3.x是否支持Jakarta EE 9?如果支持,用户可能只需要升级EhCache版本,而无需替换。 然后,我需要为每个替代方案提供配置步骤,特别是如何在Spring Boot 3.3.7中集成。例如,对于Caffeine,需要添加依赖,配置缓存管理器,启用缓存注解等。 同时,需要注意用户可能遇到的问题,比如依赖的Jakarta兼容性,如引用[3]提到的,所有javax包需要改为jakarta,所以替代方案必须支持Jakarta EE 9。例如,Caffeine可能不涉及这些包,所以安全;而Redis的Spring Boot Starter可能已经适配了。 接下来,我需要确保提到的每个方案在Spring Boot 3.3.7中可用,并且有相应的依赖和配置示例。例如,Caffeine的依赖是spring-boot-starter-cache和Caffeine本身,配置在application.properties中设置缓存类型。 另外,用户可能需要知道如何迁移现有的EhCache配置到新的缓存方案。比如,从EhCache的XML配置转换到Caffeine的配置参数,或者使用Redis的配置方式。 最后,要生成相关问题,帮助用户进一步探索,比如性能比较、具体配置步骤、迁移注意事项等。</think>在Spring Boot 3.3.7中替换EhCacheCache的替代方案及实现步骤如下: ### 1. **Caffeine(推荐本地缓存方案)** Caffeine是高性能Java本地缓存库,Spring Boot原生支持,适用于单机高并发场景。 ```java // 添加依赖(pom.xml) <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> </dependency> // 配置类 @Configuration @EnableCaching public class CacheConfig { @Bean public CacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine(Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .maximumSize(1000)); return cacheManager; } } ``` 在`application.properties`中设置: ```properties spring.cache.type=caffeine ``` ### 2. **Redis(分布式缓存方案)** 适合需要跨服务共享缓存的分布式场景[^2]。 ```java // 添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> // 配置类 @Configuration @EnableCaching public class RedisCacheConfig { @Bean public RedisConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory("localhost", 6379); } @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(30)); return RedisCacheManager.builder(factory) .cacheDefaults(config) .build(); } } ``` ### 3. **Hazelcast(内存数据网格)** 提供分布式缓存和计算能力,适合大规模数据处理。 ```java // 添加依赖 <dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast</artifactId> </dependency> <dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-spring</artifactId> </dependency> // 配置类 @Configuration @EnableCaching public class HazelcastConfig { @Bean public Config hazelcastConfig() { Config config = new Config(); config.getNetworkConfig().setPort(5701); return config; } @Bean public CacheManager cacheManager(HazelcastInstance hazelcastInstance) { return new HazelcastCacheManager(hazelcastInstance); } } ``` ### 4. **检查EhCache 3.x兼容性** 若仍需使用EhCache,需确保升级到支持Jakarta EE的版本[^3]: ```xml <dependency> <groupId>org.ehcache</groupId> <artifactId>ehcache</artifactId> <version>3.10.0</version> </dependency> ``` 配置类需显式指定EhCache3实现: ```java @Bean public JCacheManagerFactoryBean ehCacheManagerFactory() { return new JCacheManagerFactoryBean(); } @Bean public CacheManager cacheManager() { return new JCacheCacheManager(ehCacheManagerFactory().getObject()); } ``` ### 迁移注意事项 - 移除旧版EhCache 2.x依赖,避免与Jakarta EE冲突 - 缓存注解(如`@Cacheable`)可保持语法不变 - 分布式缓存需调整序列化机制(如Redis使用JSON序列化)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值