Spring 框架中後備 Bean 指南
1. 概述
在本教程中,我們將討論 Spring 框架中後備 bean 的概念。 Fallback beans 是在 Spring Framework 版本 6.2.0-M1 中引入的。當相同類型的另一個 bean 不可用或無法初始化時,它們提供了替代實作。
這在我們想要優雅地處理故障並提供回退機制以確保應用程式繼續運行的情況下非常有用。
2. 主要 Bean 和後備 Bean
在Spring應用程式中,我們可以定義多個相同類型的bean。預設情況下,Spring 使用 bean 名稱和類型來識別 bean。當我們有多個具有相同名稱和類型的 bean 時,我們可以使用@Primary註解將其中一個標記為主 bean,以優先於其他 bean。如果在初始化應用程式上下文時建立了多個相同類型的 bean,並且我們想要指定預設應使用哪個 bean,則這非常有用。
類似地,我們可以定義一個後備 bean,以便在沒有其他符合條件的 bean 可用時提供替代實作。我們可以使用@Fallback註解將bean標記為後備bean。只有當沒有其他同名 bean 可用時,後備 bean 才會被注入到應用程式上下文中。
3. 程式碼範例
讓我們看一個範例來示範 Spring 應用程式中主 Bean 和後備 Bean 的用法。我們將創建一個使用不同訊息服務發送訊息的小型應用程式。假設我們在生產和非生產環境中擁有多個訊息服務,並且需要在它們之間切換以優化效能和成本。
3.1.訊息介面
首先,讓我們為我們的服務定義一個介面:
`public interface MessagingService {
void sendMessage(String text);
}`
這個介面有一種方法將提供的文字作為訊息發送。
3.2.初級豆
接下來,我們將訊息傳遞服務的實作定義為主 bean:
`@Service
@Profile("production")
@Primary
public class ProductionMessagingService implements MessagingService {
@Override
public void sendMessage(String text) {
// implementation in production environment
}
}`
在此實作中,我們使用@Profile註解來指定該bean僅在production檔處於活動狀態時才可用。我們還使用@Primary註釋將其標記為主要 bean。
3.3.非主Bean
讓我們將訊息服務的另一個實作定義為非主 bean:
`@Service
@Profile("!test")
public class DevelopmentMessagingService implements MessagingService {
@Override
public void sendMessage(String text) {
// implementation in development environment
}
}`
在此實作中,我們使用@Profile註解來指定當test設定檔不活動時此 bean 可用。這意味著它將在除test設定檔之外的所有設定檔中可用。
3.4.後備豆
最後,讓我們為訊息服務定義一個後備 bean:
`@Service
@Fallback
public class FallbackMessagingService implements MessagingService {
@Override
public void sendMessage(String text) {
// fallback implementation
}
}`
在此實作中,我們使用@Fallback註解將此 bean 標記為後備 bean。只有當沒有其他相同類型的 Bean 可用時,才會注入該 Bean。
4. 測試
現在,讓我們透過自動組裝訊息服務並根據活動設定檔檢查使用哪個實作來測試我們的應用程式。
4.1.無簡介
在第一個測試中,我們不啟動任何設定檔。由於production設定檔未激活, ProductionMessagingService不可用,而其他兩個 bean 可用。
當我們測試訊息服務時,它應該使用DevelopmentMessagingService ,因為它優先於後備 bean:
`@RunWith(SpringRunner.class)
@SpringBootTest(classes = {FallbackMessagingService.class, DevelopmentMessagingService.class, ProductionMessagingService.class})
public class DevelopmentMessagingServiceUnitTest {
@Autowired
private MessagingService messagingService;
@Test
public void givenNoProfile_whenSendMessage_thenDevelopmentMessagingService() {
assertEquals(messagingService.getClass(), DevelopmentMessagingService.class);
}
}`
4.2.生產概況
接下來,讓我們啟動production設定檔。現在ProductionMessagingService應該可用,並且其他兩個 bean 也可用。
當我們測試訊息傳遞服務時,它應該使用ProductionMessagingService ,因為它被標記為主要 bean:
`@RunWith(SpringRunner.class)
@SpringBootTest(classes = {FallbackMessagingService.class, DevelopmentMessagingService.class, ProductionMessagingService.class})
@ActiveProfiles("production")
public class ProductionMessagingServiceUnitTest {
@Autowired
private MessagingService messagingService;
@Test
public void givenProductionProfile_whenSendMessage_thenProductionMessagingService() {
assertEquals(messagingService.getClass(), ProductionMessagingService.class);
}
}`
4.3.測試簡介
最後,讓我們啟動test設定檔。這將從上下文中刪除DevelopmentMessagingService bean。由於我們已經刪除了production配置文件,因此ProductionMessagingService也不可用。
在這種情況下,訊息傳遞服務應該使用FallbackMessagingService ,因為它是唯一可用的 bean:
`@RunWith(SpringRunner.class)
@SpringBootTest(classes = {FallbackMessagingService.class, DevelopmentMessagingService.class, ProductionMessagingService.class})
@ActiveProfiles("test")
public class FallbackMessagingServiceUnitTest {
@Autowired
private MessagingService messagingService;
@Test
public void givenTestProfile_whenSendMessage_thenFallbackMessagingService() {
assertEquals(messagingService.getClass(), FallbackMessagingService.class);
}
}`
5. 結論
在本教程中,我們討論了 Spring 框架中後備 bean 的概念。我們了解如何定義主要 bean 和後備 bean,以及如何在 Spring 應用程式中使用它們。當任何其他符合條件的 bean 不可用時,後備 bean 提供替代實作。當根據活動設定檔或其他條件在不同實作之間切換時,這可能很有用。
與往常一樣,程式碼範例可在 GitHub 上取得。