在Spring Boot快取API - Code Factory

banq發表於2020-05-10

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="employee", key="#location")
public Employee findEmployee(Location location)
@Cacheable(value="employee", key="#location.name")
public Employee findEmployee(Location location)
@Cacheable(value="employee", key="T(classType).hash(location)")
public Employee findEmployee(Location location)

我們還可以使用條件快取。例如:

@Cacheable(value="employee", key="#locationName.length > 5")
public Employee findEmployee(String locationName)

@CachePut

有時我們需要手動操作快取,以在方法呼叫之前放置(更新)快取。這將允許我們更新快取,也將允許執行該方法。該方法將始終執行,並將其結果放入快取(根據@CachePut選項)。

它支援與@Cacheable快取填充相同的選項,應該用於快取填充,而不是方法流優化。

請注意,通常不建議在同一方法上使用@CachePut和@Cacheable批註,因為它們的行為不同。後者導致通過使用快取跳過方法執行,而前者則強制執行以便執行快取更新。

這會導致意外的行為,並且除了特定的極端情況(例如具有相互排斥條件的註釋)外,應避免此類宣告。

@CacheEvict

當我們需要移出(刪除)先前載入的主資料的快取時使用它。當執行CacheEvict註釋的方法時,它將清除快取。

我們可以在此處指定鍵以刪除快取,如果需要刪除快取的所有條目,則需要使用allEntries=true。當需要清除整個快取區域時,此選項非常有用–而不是刪除每個條目(由於效率低下,這將需要很長時間),所有條目都將在一次操作中被刪除。

@Caching

當我們需要雙方都需要CachePut和CacheEvict。

SpringBootCachingApplication.java案例:

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

StudentController.java:

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

Student.java:

public class Student {
String id;
 String name;
 int age;
 
 public Student(String id, String name, int age) {
  this.id = id;
  this.name = name;
  this.age = age;
 }
public String getId() {
  return id;
 }
public void setId(String id) {
  this.id = id;
 }
public String getName() {
  return name;
 }
public void setName(String name) {
  this.name = name;
 }
public int getAge() {
  return age;
 }
public void setAge(int age) {
  this.age = age;
 }
}

StudentService.java:

@Service
public class StudentService {
@Cacheable("student")
 public Student getStudentByID(String id) {
  try {
   System.out.println("Sleep for 5 seconds.");
   Thread.sleep(5000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  return new Student("1", "Code Factory", 18);
 }
}

訪問:http://localhost:8080/student/1

您將得到一個物件的JSON響應Student。需要注意的是,第一次響應至少需要5秒鐘,然後相同URL的後續響應會更快。

 

相關文章