Spring Framework 5和EhCache 3.5

Ser*_*gey 4 spring spring-mvc ehcache ehcache-3

我试图在基于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>
Run Code Online (Sandbox Code Playgroud)

然后在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>
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

Spring Boot配置:

@SpringBootApplication
@EnableCaching
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是当我调用此端点时,我得到一个例外:

无法为Builder [public org.Order org.OrderController.findById(int)]缓存= [orders]查找名为“ orders”的缓存 键=''| keyGenerator =''| | cacheManager =''| | cacheResolver =''| 条件=''| 除非=''| sync ='false'

然后,我尝试使用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;
}
Run Code Online (Sandbox Code Playgroud)

但是由于异常而无法编译:

无法解析类型net.sf.ehcache.CacheManager。从所需的.class文件间接引用

请指教。

Hen*_*nri 7

这里杂乱无章。您正在使用的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>
Run Code Online (Sandbox Code Playgroud)

步骤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>
Run Code Online (Sandbox Code Playgroud)

第3步:application.properties需要使用此行找到ehcache.xml

spring.cache.jcache.config=classpath:ehcache.xml
Run Code Online (Sandbox Code Playgroud)

请注意,由于在类路径中找到了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++;
        }
    }
Run Code Online (Sandbox Code Playgroud)


Ess*_*Boy 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>
Run Code Online (Sandbox Code Playgroud)

使用ehcache 3:

这是应用程序:

@SpringBootApplication
@EnableCaching
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是application.yml

spring:
  cache:
    ehcache:
      config: ehcache.xml
Run Code Online (Sandbox Code Playgroud)

这里有一个带有用于测试的计数器的服务

@Service
public class OrderService {

    public static int counter=0;

    @Cacheable("orders")
    public Order findById(Long id) {
        counter++;
        return new Order(id, "desc_" + id);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个测试来证明它正在使用缓存:

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

请参阅此处的工作示例。