原文: https://howtodoinjava.com/spring-boot2/ehcache3-config-example/

学习使用 ehcache 3.xspring boot 应用程序中配置缓存。 学习使用 基于注解的缓存配置 ,以及使用CacheManager手动更新缓存。

1. Maven 依赖

在此示例中,我们使用的是 Spring 运行版本2.1.6.RELEASE。 较早的 spring boot 版本支持net.sf.ehcache软件包下的ehcache 2.x。 Spring Boot 支持ehcache 3.x的新版本可在org.ehcache软件包下获得。

Ehcache 版本 3 是 JSR-107 缓存管理器的实现。

我们需要以下依赖项来添加缓存功能。

  • spring-boot-starter-cache
  • ehcacheorg.ehcache
  • 缓存 APIjavax.cache

pom.xml

  1. <project xmlns="http://maven.apache.org/POM/4.0.0"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>com.company</groupId>
  6. <artifactId>SpringBootEhcache</artifactId>
  7. <version>0.0.1-SNAPSHOT</version>
  8. <packaging>jar</packaging>
  9. <name>SpringBootEhcache</name>
  10. <url>http://maven.apache.org</url>
  11. <parent>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-parent</artifactId>
  14. <version>2.1.6.RELEASE</version>
  15. <relativePath />
  16. </parent>
  17. <properties>
  18. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  19. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  20. <java.version>1.8</java.version>
  21. <skipTests>true</skipTests>
  22. </properties>
  23. <dependencies>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-cache</artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.ehcache</groupId>
  30. <artifactId>ehcache</artifactId>
  31. </dependency>
  32. <dependency>
  33. <groupId>javax.cache</groupId>
  34. <artifactId>cache-api</artifactId>
  35. </dependency>
  36. </dependencies>
  37. <build>
  38. <plugins>
  39. <plugin>
  40. <groupId>org.springframework.boot</groupId>
  41. <artifactId>spring-boot-maven-plugin</artifactId>
  42. </plugin>
  43. </plugins>
  44. </build>
  45. </project>

2. application.properties

Spring 的自动配置可以找到 Ehcache 的 JSR-107 实现。 但是,默认情况下不会创建任何缓存,因为 Spring 和 Ehcache 都不会寻找默认的ehcache.xml文件。 我们必须专门提供必须使用的 ehcache 配置文件路径。

application.properties

  1. spring.cache.jcache.config=classpath:ehcache.xml

3. ehcache.xml

ehcache.xml文件中,配置缓存名称及其属性。

ehcache 文档中找到属性的完整列表。

ehcache.xml

  1. <config
  2. xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
  3. xmlns='http://www.ehcache.org/v3'
  4. xmlns:jsr107='http://www.ehcache.org/v3/jsr107'>
  5. <service>
  6. <jsr107:defaults enable-statistics="true"/>
  7. </service>
  8. <cache alias="employeeCache">
  9. <key-type>java.lang.Long</key-type>
  10. <value-type>com.company.Employee</value-type>
  11. <expiry>
  12. <ttl unit="seconds">10000</ttl>
  13. </expiry>
  14. <listeners>
  15. <listener>
  16. <class>com.company.CustomCacheEventLogger</class>
  17. <event-firing-mode>ASYNCHRONOUS</event-firing-mode>
  18. <event-ordering-mode>UNORDERED</event-ordering-mode>
  19. <events-to-fire-on>CREATED</events-to-fire-on>
  20. <events-to-fire-on>UPDATED</events-to-fire-on>
  21. <events-to-fire-on>EXPIRED</events-to-fire-on>
  22. <events-to-fire-on>REMOVED</events-to-fire-on>
  23. <events-to-fire-on>EVICTED</events-to-fire-on>
  24. </listener>
  25. </listeners>
  26. <resources>
  27. <heap unit="entries">2000</heap>
  28. <offheap unit="MB">100</offheap>
  29. </resources>
  30. </cache>
  31. </config>

4. CacheEventListener

我们还使用了事件监听器,该事件监听器将在创建,删除或更新缓存条目时记录缓存事件。

CustomCacheEventLogger.java

  1. package com.company;
  2. import org.ehcache.event.CacheEvent;
  3. import org.ehcache.event.CacheEventListener;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. public class CustomCacheEventLogger implements CacheEventListener<Object, Object> {
  7. private static final Logger LOG = LoggerFactory.getLogger(CustomCacheEventLogger.class);
  8. @Override
  9. public void onEvent(CacheEvent cacheEvent) {
  10. LOG.info("Cache event = {}, Key = {}, Old value = {}, New value = {}", cacheEvent.getType(),
  11. cacheEvent.getKey(), cacheEvent.getOldValue(), cacheEvent.getNewValue());
  12. }
  13. }

5. @EnableCaching

它启用 Spring 的注解驱动的缓存管理功能,并在调用@Cacheable注解方法时启用对代理拦截器的支持。

CacheConfig.java

  1. import org.springframework.cache.annotation.EnableCaching;
  2. import org.springframework.context.annotation.Configuration;
  3. @Configuration
  4. @EnableCaching
  5. public class CacheConfig {
  6. }

6. @Cacheable注解

要缓存从方法调用返回的数据,我们可以在方法上使用@Cacheable注解。 使用其属性cacheNameskey来指代缓存和缓存条目的键属性。

EmployeeManager.java

  1. import java.util.HashMap;
  2. import org.springframework.cache.annotation.Cacheable;
  3. import org.springframework.stereotype.Service;
  4. @Service
  5. public class EmployeeManager
  6. {
  7. static HashMap<Long, Employee> db = new HashMap<>();
  8. static {
  9. db.put(1L, new Employee(1L, "Alex", "Gussin"));
  10. db.put(2L, new Employee(2L, "Brian", "Schultz"));
  11. }
  12. @Cacheable(cacheNames="employeeCache", key="#id")
  13. public Employee getEmployeeById(Long id) {
  14. System.out.println("Getting employee from DB");
  15. return db.get(id);
  16. }
  17. }

7. Spring CacheManager API

有时,在使用注解似乎不是完美解决方案的情况下,我们可能需要使用缓存。 在这种情况下,我们可以使用org.springframework.cache.CacheManagerorg.springframework.cache.Cache抽象来访问并利用 ehcache 添加和访问缓存条目。

要使用CacheManager,我们必须首先自动装配到 spring 组件中,并使用它的getCache(name)方法来按名称获取缓存实例。

访问缓存后,我们可以使用其get()put()方法来添加和访问缓存条目。

  1. //1
  2. @Autowired
  3. private CacheManager cacheManager;
  4. //2
  5. Cache cache = cacheManager.getCache("myCache");
  6. cache.put(3L, "Hello");
  7. String value = cache.get(3L).get();

8. Spring Boot ehcache 3 示例 – 演示

我正在创建一个模型类Employee,其实例将被缓存。

Employee.java

  1. import java.io.Serializable;
  2. public class Employee implements Serializable
  3. {
  4. private static final long serialVersionUID = 5517244812959569947L;
  5. private Long id;
  6. private String firstName;
  7. private String lastName;
  8. public Employee() {
  9. super();
  10. }
  11. public Employee(Long id, String firstName, String lastName) {
  12. super();
  13. this.id = id;
  14. this.firstName = firstName;
  15. this.lastName = lastName;
  16. }
  17. //Getters and setters
  18. @Override
  19. public String toString() {
  20. return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]";
  21. }
  22. }

现在在演示应用程序类中,我正在使用@Cacheable注解测试基于注解的缓存访问,并使用CacheManager进行手动缓存访问。

Application.java

  1. import org.springframework.beans.factory.annotation.Autowired;
  2. import org.springframework.boot.CommandLineRunner;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. import org.springframework.cache.Cache;
  6. import org.springframework.cache.CacheManager;
  7. import org.springframework.context.ApplicationContext;
  8. import org.springframework.context.annotation.Bean;
  9. @SpringBootApplication
  10. public class Application {
  11. @Autowired
  12. private CacheManager cacheManager;
  13. @Autowired
  14. private EmployeeManager employeeManager;
  15. public static void main(String[] args) {
  16. SpringApplication.run(Application.class, args);
  17. }
  18. @Bean
  19. public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
  20. return args -> {
  21. //This will hit the database
  22. System.out.println(employeeManager.getEmployeeById(1L));
  23. //This will hit the cache - verify the message in console output
  24. System.out.println(employeeManager.getEmployeeById(1L));
  25. //Access cache instance by name
  26. Cache cache = cacheManager.getCache("employeeCache");
  27. //Add entry to cache
  28. cache.put(3L, new Employee(3L, "Charles", "Dave"));
  29. //Get entry from cache
  30. System.out.println(cache.get(3L).get());
  31. };
  32. }
  33. }

程序输出。

Console

  1. //First hit to "employeeManager.getEmployeeById(1L)"
  2. Getting employee from DB
  3. Employee [id=1, firstName=Alex, lastName=Gussin]
  4. 2019-07-10 15:42:32.371 INFO 11956 --- [e [_default_]-0] com.company.CustomCacheEventLogger
  5. : Cache event = CREATED, Key = 1, Old value = null, New value = Employee [id=1, firstName=Alex, lastName=Gussin]
  6. //Second hit to "employeeManager.getEmployeeById(1L)"
  7. Employee [id=1, firstName=Alex, lastName=Gussin]
  8. //cache.put(3L, new Employee(3L, "Charles", "Dave"));
  9. 2019-07-10 15:42:32.399 INFO 11956 --- [e [_default_]-0] com.company.CustomCacheEventLogger : Cache event = CREATED, Key = 3, Old value = null, New value = Employee [id=3, firstName=Charles, lastName=Dave]
  10. //System.out.println(cache.get(3L).get());
  11. Employee [id=3, firstName=Charles, lastName=Dave]

请在评论中使用 ehcache 3 将有关此 spring boot 2 缓存示例的问题交给我。

学习愉快!

下载源码