Spring在缓存方面具有一些不错的功能,并且使用Spring缓存API的抽象非常简单。
缓存是一种增强系统性能的机制。它是位于应用程序和持久数据库之间的临时内存。高速缓存存储器存储最近使用的数据项,以尽可能减少数据库命中的次数。
Spring框架为不同的缓存提供程序提供了缓存抽象api。API的用法非常简单,但功能非常强大。今天,我们将在缓存中看到基于注释的Java配置。注意,我们也可以通过XML配置实现类似的功能。
@EnableCaching
它启用了Spring的注释驱动的缓存管理功能。在spring boot项目中,我们需要将其添加到带有注释的启动应用程序类中@SpringBootApplication。Spring提供了一个并发哈希图作为默认缓存,但是我们也可以重写CacheManager以轻松注册外部缓存提供程序。
@Cacheable
它在方法级别上用于使spring知道该方法的响应是可缓存的。Spring管理此方法对注释属性中指定的缓存的请求/响应。例如,@Cacheable ("cacheName1", “cacheName2”)。
@Cacheable注释具有更多选项。就像我们可以从方法的请求中指定缓存的键一样。如果未指定任何内容,spring将使用所有类字段并将其用作缓存键(主要是HashCode)来维护缓存,但是我们可以通过提供键信息来覆盖此行为。
@Cacheable(value=<font>"employee"</font><font>, key=</font><font>"#location"</font><font>) <b>public</b> Employee findEmployee(Location location) @Cacheable(value=</font><font>"employee"</font><font>, key=</font><font>"#location.name"</font><font>) <b>public</b> Employee findEmployee(Location location) @Cacheable(value=</font><font>"employee"</font><font>, key=</font><font>"T(classType).hash(location)"</font><font>) <b>public</b> Employee findEmployee(Location location) </font>
我们还可以使用条件缓存。例如:
@Cacheable(value=<font>"employee"</font><font>, key=</font><font>"#locationName.length > 5"</font><font>) <b>public</b> Employee findEmployee(String locationName) </font>
@CachePut
有时我们需要手动操作缓存,以在方法调用之前放置(更新)缓存。这将允许我们更新缓存,也将允许执行该方法。该方法将始终执行,并将其结果放入缓存(根据@CachePut选项)。
它支持与@Cacheable缓存填充相同的选项,应该用于缓存填充,而不是方法流优化。
请注意,通常不建议在同一方法上使用@CachePut和@Cacheable批注,因为它们的行为不同。后者导致通过使用缓存跳过方法执行,而前者则强制执行以便执行缓存更新。
这会导致意外的行为,并且除了特定的极端情况(例如具有相互排斥条件的注释)外,应避免此类声明。
@CacheEvict
当我们需要移出(删除)先前加载的主数据的缓存时使用它。当执行CacheEvict注释的方法时,它将清除缓存。
我们可以在此处指定键以删除缓存,如果需要删除缓存的所有条目,则需要使用allEntries=true。当需要清除整个缓存区域时,此选项非常有用–而不是删除每个条目(由于效率低下,这将需要很长时间),所有条目都将在一次操作中被删除。
@Caching
当我们需要双方都需要CachePut和CacheEvict。
SpringBootCachingApplication.java案例:
@SpringBootApplication @EnableCaching <b>public</b> <b>class</b> SpringBootCachingApplication { <b>public</b> <b>static</b> <b>void</b> main(String[] args) { SpringApplication.run(SpringBootCachingApplication.<b>class</b>, args); } }
StudentController.java:
@RestController <b>public</b> <b>class</b> StudentController { @Autowired StudentService studentService; @GetMapping(<font>"/student/{id}"</font><font>) <b>public</b> Student findStudentByID(@PathVariable String id) { System.out.println(</font><font>"Student ID : "</font><font> + id); <b>return</b> studentService.getStudentByID(id); } } </font>
Student.java:
<b>public</b> <b>class</b> Student { String id; String name; <b>int</b> age; <b>public</b> Student(String id, String name, <b>int</b> age) { <b>this</b>.id = id; <b>this</b>.name = name; <b>this</b>.age = age; } <b>public</b> String getId() { <b>return</b> id; } <b>public</b> <b>void</b> setId(String id) { <b>this</b>.id = id; } <b>public</b> String getName() { <b>return</b> name; } <b>public</b> <b>void</b> setName(String name) { <b>this</b>.name = name; } <b>public</b> <b>int</b> getAge() { <b>return</b> age; } <b>public</b> <b>void</b> setAge(<b>int</b> age) { <b>this</b>.age = age; } }
StudentService.java:
@Service <b>public</b> <b>class</b> StudentService { @Cacheable(<font>"student"</font><font>) <b>public</b> Student getStudentByID(String id) { <b>try</b> { System.out.println(</font><font>"Sleep for 5 seconds."</font><font>); Thread.sleep(5000); } <b>catch</b> (InterruptedException e) { e.printStackTrace(); } <b>return</b> <b>new</b> Student(</font><font>"1"</font><font>, </font><font>"Code Factory"</font><font>, 18); } } </font>
访问: http://localhost:8080/student/1
您将得到一个对象的JSON响应Student。需要注意的是,第一次响应至少需要5秒钟,然后相同URL的后续响应会更快。