Spring Boot+Jetty配置Hibernate缓存URI报错,求正确配置方法
这个问题的核心原因在于:Tomcat的默认URL处理机制自带了classpath协议的解析支持,但Jetty并没有默认注册这个协议的处理器。当Hibernate通过JCache规范尝试解析classpath:/ehcache.xml这个URI时,Jetty无法识别classpath协议,就会抛出unknown protocol: classpath的异常。
下面提供几种可行的解决方案,按推荐程度排序:
方法1:使用Hibernate针对EhCache的专属配置(最简单)
如果你的缓存实现是EhCache,直接替换原来的JCache URI配置为Hibernate对EhCache的特定配置项,绕开JCache的URI解析流程:
# 替换原来的spring.jpa.properties.hibernate.javax.cache.uri配置 spring.jpa.properties.hibernate.cache.ehcache.configurationResourceName=classpath:/ehcache.xml
这个配置是Hibernate直接处理的,它会通过Spring的类加载器读取classpath下的配置文件,不需要依赖Jetty的URL协议支持,所以在Tomcat和Jetty下都能正常工作。
方法2:注册Classpath协议处理器到Jetty
如果你坚持要使用JCache的URI配置方式,可以在Spring Boot启动时手动注册classpath协议的URL处理器,让Jetty能够识别这个协议:
@SpringBootApplication public class YourApplication { public static void main(String[] args) { // 注册classpath协议的URL处理器 URL.setURLStreamHandlerFactory(protocol -> { if ("classpath".equals(protocol)) { return new org.springframework.core.io.ClassPathResource.ClassPathURLStreamHandler(); } return null; // 其他协议使用默认处理器 }); SpringApplication.run(YourApplication.class, args); } }
注册完成后,原来的配置spring.jpa.properties.hibernate.javax.cache.uri=classpath:/ehcache.xml就可以正常生效了。
方法3:自定义CacheManager手动加载配置
通过Spring配置类手动初始化JCache的CacheManager,直接指定ehcache.xml的路径,不需要依赖Hibernate的URI配置:
import org.ehcache.jsr107.EhcacheCachingProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.cache.CacheManager; import java.net.URI; @Configuration public class CacheConfig { @Bean public CacheManager jCacheManager() throws Exception { EhcacheCachingProvider cachingProvider = new EhcacheCachingProvider(); URI configUri = getClass().getResource("/ehcache.xml").toURI(); return cachingProvider.getCacheManager(configUri, getClass().getClassLoader()); } }
添加这个配置类后,你可以移除原来的spring.jpa.properties.hibernate.javax.cache.uri配置,Spring会自动将这个自定义的CacheManager注入到Hibernate中使用。
内容的提问来源于stack exchange,提问作者user1750751

