Infinispan同时作为Hibernate二级缓存与Spring缓存的共享配置问题
Spring 7 + Hibernate 7.2 + Infinispan 16.1 缓存管理器共享方案
1. 单独创建缓存管理器是否可行?
可行,但不推荐。原因如下:
- 内存资源浪费:两个独立的
EmbeddedCacheManager实例会占用双倍内存,缓存数据量大时影响更明显 - 数据一致性风险:Spring缓存与Hibernate二级缓存属于独立空间,同一份数据可能出现版本不一致,引发业务逻辑错误
- 配置冗余:需要重复维护两套Infinispan配置,增加后续维护成本
2. 共享缓存管理器的优势
- 资源复用:减少内存占用,避免重复初始化的性能开销
- 数据统一:Spring缓存与Hibernate二级缓存共用同一缓存空间,数据状态保持一致
- 配置集中:仅需维护一套Infinispan配置,降低维护复杂度
3. 共享缓存管理器实现示例
步骤1:配置Spring管理的EmbeddedCacheManager Bean
import org.infinispan.configuration.global.GlobalConfigurationBuilder; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.manager.DefaultCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class InfinispanConfig { @Bean(destroyMethod = "stop") public EmbeddedCacheManager embeddedCacheManager() { GlobalConfigurationBuilder globalConfig = GlobalConfigurationBuilder.defaultClusteredBuilder(); // 添加自定义配置(如序列化规则、集群模式等) // globalConfig.serialization().addMarshaller(new CustomMarshaller()); return new DefaultCacheManager(globalConfig.build()); } }
步骤2:自定义Hibernate缓存区域工厂,复用Spring的缓存管理器
继承InfinispanRegionFactory,从Spring上下文获取已有的EmbeddedCacheManager:
import org.infinispan.hibernate.cache.v72.InfinispanRegionFactory; import org.infinispan.manager.EmbeddedCacheManager; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import java.util.Map; @Component public class SpringInjectedInfinispanRegionFactory extends InfinispanRegionFactory implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Override protected EmbeddedCacheManager createCacheManager(Map properties) { // 从Spring上下文获取已配置的缓存管理器 return applicationContext.getBean(EmbeddedCacheManager.class); } @Override protected void stopCacheManager() { // 禁止Hibernate关闭缓存管理器(由Spring统一管理生命周期) } }
步骤3:配置Hibernate使用自定义区域工厂
在Spring的LocalSessionFactoryBean中配置Hibernate参数:
import org.springframework.orm.hibernate5.LocalSessionFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; import java.util.Properties; @Configuration public class HibernateConfig { @Bean public LocalSessionFactoryBean sessionFactory(DataSource dataSource) { LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); sessionFactory.setDataSource(dataSource); sessionFactory.setPackagesToScan("com.yourpackage.entity"); Properties hibernateProps = new Properties(); hibernateProps.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect"); hibernateProps.setProperty("hibernate.cache.use_second_level_cache", "true"); // 指定自定义的区域工厂类 hibernateProps.setProperty("hibernate.cache.region.factory_class", "com.yourpackage.SpringInjectedInfinispanRegionFactory"); // 禁止Hibernate自动关闭缓存管理器 hibernateProps.setProperty("hibernate.cache.infinispan.cache_manager_stop", "false"); sessionFactory.setHibernateProperties(hibernateProps); return sessionFactory; } }
注意事项
- 确保
SpringInjectedInfinispanRegionFactory被Spring扫描到(通过@Component或手动注册Bean) - 若使用Infinispan集群模式,需在
EmbeddedCacheManager配置中统一设置集群参数,避免通信异常
内容的提问来源于stack exchange,提问作者dali
相关产品推荐
相关产品推荐

