Spring Boot – EhCaching
EhCache 是一个基于 Java 的开源缓存。它用于提高性能。它的当前版本是 3。EhCache 提供了 JSR-107 缓存管理器的实现。 EhCache 的特点如下:
- 它快速、轻量级、灵活且可扩展。
- 它允许我们执行 Serializable 和 Object
- 它还提供缓存驱逐策略,如 LRU、LFU、FIFO、
EhCaching 存储层如下:
- On-Heap Store: Java堆内存用于存储缓存条目。
- 堆外存储:它将缓存条目存储到主内存(RAM)中。
- 磁盘存储:它使用磁盘来存储缓存条目。
- Clustered Store:远程服务器用于存储缓存条目。
EhCache 使用模式:
EhCache 使用的访问模式如下:
- Cache-aside:可用于从数据存储读取和更新数据的操作。
- Cache-as-SoR(系统记录):此模式将 SOR 读取和写入活动委托给缓存,以便应用程序代码免除此责任。
- 通读:此模式在从缓存中读取数据时复制缓存侧模式。
- 直写:此模式在将数据写入缓存时复制缓存侧模式。
- 后写:这是一种缓存策略,其中缓存层本身连接到后备数据库。
使用 EhCaching 时要记住的要点:
1.我们需要在pom.xml中添加如下依赖。
XML
org.springframework.boot
spring-boot-starter-web
2.6.1
org.springframework.boot
spring-boot-starter-cache
2.6.1
javax.cache
cache-api
1.1.1
org.ehcache
ehcache
3.8.1
Java
@Configuration
// used for enabling caching
@EnableCaching
public class CacheConfig {
}
XML
Java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan("com.codippa")
public class CachingApplication {
public static void main(String[] args) {
SpringApplication.run(CachingApplication.class, args);
}
}
Java
public class Post {
private Integer postId;
private String title;
public Post(Integer postId, String title)
{
this.postId = postId;
this.title = title;
}
public Integer getPostId() { return postId; }
public void setPostId(Integer postId)
{
this.postId = postId;
}
public String getTitle() { return title; }
public void setTitle(String title)
{
this.title = title;
}
}
Java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.beans.factory.annotation.Autowired;
@Controller
public class PostController {
@Autowired
PostService service;
@GetMapping("/posts/{id}")
public @ResponseBody Post findById(@PathVariable("id") Integer postId) {
return service.findById(postId);
}
@PostMapping("/updatepost")
public void updatePost(Post post) {
service.updatePost(post);
}
@DeleteMapping("/posts/{id}")
public void deleteById(@PathVariable("id") Integer postId) {
service.deleteById(postId);
}
}
Java
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class PostService {
@Cacheable("posts")
public Post findById(Integer postId) {
System.out.println("Fetching Post");
return new Post(postId, "Demo post");
}
@CachePut("posts")
public void updatePost(Post post) {
// update post
}
@CacheEvict("posts")
public void deleteById(Integer postId) {
// delete post
}
}
2.接下来我们必须打开 application.properties 文件并使用以下属性配置 EhCache。
# configuring ehcache.xml
spring.cache.jcache.config=classpath:ehcache.xml
3. @EnableCaching 注解触发一个后处理器,检查每个 Spring bean 是否存在公共的缓存注解方法。如果找到这样的注释,将自动创建一个代理来拦截方法调用,从而相应地处理缓存行为。我们可以使用@EnableCaching 注解来启用 EhCaching,如下所示:
Java
@Configuration
// used for enabling caching
@EnableCaching
public class CacheConfig {
}
4.这个方法级别的注解让Spring Boot知道被注解的方法返回的值是可以缓存的。每当调用带有此 @Cacheable 标记的方法时,都会应用缓存行为。特别是,Spring Boot 将检查是否已经为给定的参数调用了该方法。这涉及查找默认使用方法参数生成的密钥。如果在缓存中没有找到与计算键的方法相关的值,则目标方法将正常执行。否则,缓存的值将立即返回。 @Cacheable 带有许多参数,但使用它的简单方法是使用注释对方法进行注释,并使用将存储结果的缓存名称对其进行参数化。 @Cacheable 注解表示调用一个方法的结果或者类内的所有方法都可以被缓存。
5.我们需要创建一个 hcache.xml 文件,其中包含与缓存相关的信息,例如缓存的名称、内存中的元素数量、缓存中数据的生存时间等。
XML
示例项目
spring boot EhCaching 的一个例子如下。
主类:
Java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan("com.codippa")
public class CachingApplication {
public static void main(String[] args) {
SpringApplication.run(CachingApplication.class, args);
}
}
帖子类:
Java
public class Post {
private Integer postId;
private String title;
public Post(Integer postId, String title)
{
this.postId = postId;
this.title = title;
}
public Integer getPostId() { return postId; }
public void setPostId(Integer postId)
{
this.postId = postId;
}
public String getTitle() { return title; }
public void setTitle(String title)
{
this.title = title;
}
}
控制器类:
此类使用适当的方法映射 URL。
Java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.beans.factory.annotation.Autowired;
@Controller
public class PostController {
@Autowired
PostService service;
@GetMapping("/posts/{id}")
public @ResponseBody Post findById(@PathVariable("id") Integer postId) {
return service.findById(postId);
}
@PostMapping("/updatepost")
public void updatePost(Post post) {
service.updatePost(post);
}
@DeleteMapping("/posts/{id}")
public void deleteById(@PathVariable("id") Integer postId) {
service.deleteById(postId);
}
}
服务等级:
代码中用到的两个缓存注解解释如下:
- @CachePut :缓存对象是数据库中原始对象的副本,应该与它们相同。当原始对象发生变化时,缓存的对象应该被更新。这是使用 @CachePut 注释完成的,并应用于执行更新操作的方法。
- @CacheEvict :该注解用于表示对缓存中的数据进行远程操作,应用于从数据库中删除对象的方法
Java
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class PostService {
@Cacheable("posts")
public Post findById(Integer postId) {
System.out.println("Fetching Post");
return new Post(postId, "Demo post");
}
@CachePut("posts")
public void updatePost(Post post) {
// update post
}
@CacheEvict("posts")
public void deleteById(Integer postId) {
// delete post
}
}
为了测试缓存是否正常工作,我们必须点击 URL http://localhost:8080/posts/1,然后查看控制台。它应该打印以下输出:
输出:
Fetching Post