我尝试在基于Spring Boot 2 / Spring Framework 5的Web应用程序中使用EhCache 3.5缓存功能。
我添加了EHCache依赖:
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.0.0</version>
</dependency>
然后在src / main / resources文件夹中创建了ehcache.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
monitoring="autodetect" dynamicConfig="true">
<cache name="orders" maxElementsInMemory="100"
eternal="false" overflowToDisk="false"
memoryStoreEvictionPolicy="LFU" copyOnRead="true"
copyOnWrite="true" />
</ehcache>
Spring 5参考指南没有提到EHCache的使用,Spring 4参考指南指出:“Ehcache 3.x完全符合JSR-107标准,不需要专门的支持。”
所以我创建了控制器OrderController和REST端点:
@Cacheable("orders")
@GetMapping(path = "/{id}")
public Order findById(@PathVariable int id) {
return orderRepository.findById(id);
}
Spring Boot配置:
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
但是当我调用这个端点时,我得到一个例外:
无法为Builder找到名为'orders'的缓存[public org.Order org.OrderController.findById(int)] caches = [orders] | key =''| keyGenerator =''| cacheManager =''| cacheResolver =''| condition =''|除非=''|同步= '假'
然后我尝试使用Spring Framework 4中的示例:
@Bean
public CacheManager cacheManager() {
return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}
@Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();
cmfb.setConfigLocation(new ClassPathResource("ehcache.xml"));
cmfb.setShared(true);
return cmfb;
}
但由于例外情况,它无法编译:
无法解析net.sf.ehcache.CacheManager类型。它是从所需的.class文件间接引用的
请建议。
答案 0 :(得分:5)
这里有各种各样的东西。您正在使用的Ehcache 3通过JCache与Spring一起使用。
这就是您需要使用spring.cache.jcache.config=classpath:ehcache.xml
。
然后,您的Ehcache配置确实是Ehcache 2配置。 EhCacheCacheManager
也是如此。对于JCache,您应该使用JCacheCacheManager
。但事实上,你甚至不需要ehcache.xml
。
以下是使其有效的步骤
第1步:设置正确的依赖关系。请注意,您不需要指定父pom依赖关系管理提供的任何版本。 javax.cache现在是1.1版。
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
第2步:在ehcache.xml
中添加src/main/resources
文件。以下是一个例子。
<?xml version="1.0" encoding="UTF-8"?>
<config
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
xmlns='http://www.ehcache.org/v3'
xsi:schemaLocation="
http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.5.xsd
http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.5.xsd">
<service>
<jsr107:defaults enable-management="false" enable-statistics="true"/>
</service>
<cache alias="value">
<resources>
<heap unit="entries">2000</heap>
</resources>
</cache>
</config>
第3步:找到application.properties
ehcache.xml
spring.cache.jcache.config=classpath:ehcache.xml
请注意,由于在类路径中找到了JCache,因此Spring Cache会选择它作为缓存提供程序。因此,无需指定spring.cache.type=jcache
。
第4步:像你一样启用缓存
@SpringBootApplication
@EnableCaching
public class Cache5Application {
private int value = 0;
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(Cache5Application.class, args);
Cache5Application app = context.getBean(Cache5Application.class);
System.out.println(app.value());
System.out.println(app.value());
}
@Cacheable("value")
public int value() {
return value++;
}
}
答案 1 :(得分:2)
您需要强制它使用ehcache版本2
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.3</version>
</dependency>
使用ehcache 3:
以下是申请表:
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
这是application.yml
spring:
cache:
ehcache:
config: ehcache.xml
这是一个带有测试计数器的服务
@Service
public class OrderService {
public static int counter=0;
@Cacheable("orders")
public Order findById(Long id) {
counter++;
return new Order(id, "desc_" + id);
}
}
这是一个证明它正在使用缓存的测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class OrderServiceTest {
@Autowired
private OrderService orderService;
@Test
public void getHello() throws Exception {
orderService.findById(1l);
assertEquals(1, OrderService.counter);
orderService.findById(1l);
assertEquals(1, OrderService.counter);
orderService.findById(2l);
assertEquals(2, OrderService.counter);
}
}
有关工作示例,请参阅here。
答案 2 :(得分:0)
我做了另外的研究。 Spring Boot(来自application.properties)未选择以下配置:
spring.cache.ehcache.config=classpath:ehcache.xml
所以我创建了jcache.xml并放入了src / main / resource文件夹:
<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xsi:schemaLocation="
http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd">
<cache alias="orders">
<key-type>org.springframework.cache.interceptor.SimpleKey</key-type>
<value-type>java.util.Collections$SingletonList</value-type>
<heap unit="entries">200</heap>
</cache>
</config>
然后我将application.properties中的设置更改为
spring.cache.jcache.config=classpath:jcache.xml
现在Spring Caching正常工作。然而,如何获取ehcache.xml仍是一个问题
答案 3 :(得分:0)
面对同样的问题。
我的ehcache.xml看起来像
<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://www.ehcache.org/v3' xmlns:jsr107='http://www.ehcache.org/v3/jsr107' xsi:schemaLocation=" http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd"> <service> <jsr107:defaults> <jsr107:cache name="vehicles" template="heap-cache" /> </jsr107:defaults> </service> <cache-template name="heap-cache"> <heap unit="entries">20</heap> </cache-template> </config>
已在spring.cache.jcache.config=classpath:ehcache.xml
中配置了application.properties
在我的应用程序类上有@EnableCaching
。
我的服务实现中有@CacheResult
。
@CacheResult(cacheName =“ vehicles”)公共VehicleDetail getVehicle(@CacheKey String vehicleId)抛出VehicleServiceException
如果有人可以指出我想念的东西,那将真的很有帮助。
答案 4 :(得分:0)
hmm ..将ehcache.xml更改为,完成了技巧..
<config xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns='http://www.ehcache.org/v3'
xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
xsi:schemaLocation="
http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd">
<service>
<jsr107:defaults enable-management="true"
enable-statistics="true" />
</service>
<cache alias="vehicles" uses-template="heap-cache" />
<cache-template name="heap-cache">
<heap unit="entries">20</heap>
</cache-template>
</config>