Spring boot的缓存使用

18-09-13 banq
         

Spring框架为不同的缓存产品提供缓存抽象api,API的使用非常简单,但功能非常强大。今天我们将在缓存上看到基于注释的Java配置,请注意,我们也可以通过XML配置实现类似的功能。

@EnableCaching

它支持Spring的注释驱动的缓存管理功能,在spring boot项目中,我们需要将它添加到带注释的引导应用程序类中@SpringBootApplication。Spring默认提供了一个并发hashmap作为缺省缓存,但我们也可以覆盖CacheManager以轻松注册外部缓存提供程序。

@Cacheable

它在方法级别上使用,让spring知道该方法的响应是可缓存的。Spring将此方法的请求/响应管理到注释属性中指定的缓存。例如,@Cacheable ("cache-name1", “cache-name2”)。

@Cacheable注释有更多选项。就像我们可以从方法的请求中指定缓存的键,如果没有指定,spring使用所有类字段并将其用作缓存键(主要是HashCode)来维护缓存,但我们可以通过提供关键信息来覆盖此行为:

@Cacheable(value="books", key="#isbn")
public Book findStoryBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
 
@Cacheable(value="books", key="#isbn.rawNumber")
public Book findStoryBook (ISBN isbn, boolean checkWarehouse, boolean includeUsed)
 
@Cacheable(value="books", key="T(classType).hash(#isbn)")
public Book findStoryBook (ISBN isbn, boolean checkWarehouse, boolean includeUsed)
<p>

我们也可以使用条件缓存。例如,

@Cacheable(value="book", condition="#name.length < 50")
public Book findStoryBook (String name)
<p>

@CachePut

有时我们需要手动操作缓存,这样可在方法调用之前put(更新)缓存,这个方法让我们更新缓存,并且执行被注释的该方法,Spring执行注释方法,并将其结果放入缓存中(根据@CachePut选项)。

它与@Cacheable支持相同的选项,应该用于缓存填充,而不是方法流优化。

请注意,通常不鼓励对同一方法使用@CachePut和@Cacheable注释,因为它们具有不同的行为。虽然后者导致通过使用缓存跳过方法执行,但前者强制执行以执行缓存更新。

这会导致意外的行为,除了特定的角落情况(例如注释具有将它们彼此排除的条件)之外,应该避免这种声明。

@CacheEvict

当我们需要从缓存删除先前加载的主数据时可以使用它,当CacheEvict注释方法将被执行时,它将清除缓存。

我们可以在这里指定键来删除缓存,如果我们需要删除缓存的所有条目,那么我们需要使用allEntries=true。当需要清除整个缓存区域时,此选项会派上用场 - 而不是逐个剔除每个条目(这会花费很长时间,因为它效率低),所有条目都在一次操作中被删除。

@Caching

当同时需要CachePut和CacheEvict时,使用这个注释。

Spring启动提供与以下缓存提供程序的集成。Spring引导使用默认选项进行自动配置,如果这些选项存在于类路径中,并且我们已在spring boot应用程序中通过@EnableCaching启用了缓存。

JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)

EhCache 2.x

Hazelcast

Infinispan

Couchbase

Redis

Caffeine

Simple cache

我们可以通过覆盖缓存提供程序特定的设置来覆盖Spring starter中的特定缓存行为 - 例如

spring.cache.infinispan.config=infinispan.xml

使用案例

1. 使用缓存:

@Service
public class StudentService
{
    @Cacheable("student")
    public Student getStudentByID(String id)
    {
        try
        {
            System.out.println("Going to sleep for 5 Secs.. to simulate backend call.");
            Thread.sleep(1000*5);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
 
        return new Student(id,"Sajal" ,"V");
    }
}
<p>

服务层方法被注释@Cacheable("student"),该注释在该特定方法中启用高速缓存,并且高速缓存名称是"student"。

在该getStudentByID()方法中,我们使用有意的5秒延迟Thread.sleep(1000*5)。这只是为了了解响应是来自缓存还是真正的后端。

2. REST前端:

@RestController
public class StudentController
{
 
    @Autowired
    StudentService studentService;
 
    @GetMapping("/student/{id}")
    public Student findStudentById(@PathVariable String id)
    {
        System.out.println("Searching by ID  : " + id);
 
        return studentService.getStudentByID(id);
    }
}
<p>

3.启用缓存:

@SpringBootApplication
@EnableCaching
public class SpringCacheApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringCacheApplication.class, args);
    }
}
<p>

完整源码下载

Spring boot caching tutorial with example - HowToD