知識庫 / Spring / Spring Boot RSS 訂閱

Spring Boot Fluent Builder API 中的上下文層次結構

Spring Boot
HongKong
4
02:02 PM · Dec 06 ,2025

1. 概述

可以在 Spring Boot 中創建單獨的上下文並將其組織成層次結構。

Spring Boot 應用程序可以以多種方式定義上下文層次結構。 在本文中,我們將探討如何使用流暢構建器 API 創建多個上下文

由於我們將不深入討論如何設置 Spring Boot 應用程序,因此您可能想查看這篇文章。

2. 應用程序上下文層次結構

我們可以擁有多個應用程序上下文,它們之間存在父子關係。

上下文層次結構允許多個子上下文共享位於父上下文中的 Bean。 每個子上下文都可以覆蓋從父上下文繼承的配置。

此外,我們可以使用上下文來防止一個上下文中的 Bean 在另一個上下文中的可訪問性。這有助於創建鬆散耦合的模塊。

需要注意的是,一個上下文只能有一個父上下文,而一個父上下文可以有多個子上下文。 此外,子上下文可以訪問父上下文中的 Bean,但反之則不然。

3. 使用 <em >SpringApplicationBuilder</em > API

<em >SpringApplicationBuilder</em >> 類提供了一個流暢的 API,用於使用parent()>、<em >child()</em >> 和sibling()> 方法來創建父子上下文關係。

為了説明上下文層次結構,我們將設置一個非 Web 父級應用程序上下文,幷包含 2 個子級 Web 上下文。

為了演示這一點,我們將啓動兩個嵌入式 Tomcat 實例,每個實例都有自己的 Web 應用程序上下文,並且它們都運行在單個 JVM 中。

3.1. 父級上下文

首先,讓我們創建一個服務 Bean 及其 Bean 定義類,這些類位於父級包中。我們希望這個 Bean 返回一個問候語,該問候語將顯示給我們的 Web 應用程序的客户端:

@Service
public class HomeService implements IHomeService {

    public String getGreeting() {
        return "Welcome User";
    }
}
<p>以及 Bean 定義類:</p>
@Configuration
@ComponentScan("com.baeldung.parent")
public class ServiceConfig {}

接下來,我們將創建兩個子上下文的配置。

3.2. 子上下文

由於所有上下文都使用默認配置文件的配置,因此我們需要為無法在不同上下文中共享的屬性(例如服務器端口)提供單獨的配置。

為了防止自動配置拾取衝突的配置,我們還將類放在不同的包中。

讓我們從定義第一個子上下文的屬性文件開始:

server.port=8074
server.servlet.context-path=/ctx1

spring.application.admin.enabled=false
spring.application.admin.jmx-name=org.springframework.boot:type=Ctx1Rest,name=Ctx1Application

請注意,我們已配置了端口和上下文路徑,以及 JMX 名稱,以避免應用程序名稱衝突。

現在,讓我們為該上下文添加主配置類:

@Configuration
@ComponentScan("com.baeldung.ctx1")
@EnableAutoConfiguration
public class Ctx1Config {
    
    @Bean
    public IHomeService homeService() {
        return new GreetingService();
    }
}

此類提供了一個新的 homeService 豆的定義,它將覆蓋父類中的定義。

讓我們查看 GreetingService 類的定義:

@Service
public class GreetingService implements IHomeService {

    public String getGreeting() {
        return "Greetings for the day";
    }
}

最後,我們將為這個 Web 上下文添加一個控制器,它將使用 homeService Bean 來向用户顯示一條消息:

@RestController
public class Ctx1Controller {

    @Autowired
    private HomeService homeService;

    @GetMapping("/home")
    public String greeting() {
        return homeService.getGreeting();
    }
}

3.3. 兄弟上下文

對於我們第二個上下文,我們將創建一個與上一節中非常相似的控制器和配置類。

這次我們不會創建一個 homeService bean – 因為我們將從父上下文訪問它。

首先,讓我們為這個上下文添加一個屬性文件:

server.port=8075
server.servlet.context-path=/ctx2

spring.application.admin.enabled=false
spring.application.admin.jmx-name=org.springframework.boot:type=WebAdmin,name=SpringWebApplication

以下是兄弟應用程序的配置類:

@Configuration
@ComponentScan("com.baeldung.ctx2")
@EnableAutoConfiguration
@PropertySource("classpath:ctx2.properties")
public class Ctx2Config {}

讓我們也添加一個控制器,該控制器依賴於 HomeService

@RestController
public class Ctx2Controller {

    @Autowired
    private IHomeService homeService;

    @GetMapping("/greeting")
    public String getGreeting() {
        return homeService.getGreeting();
    }
}

在這種情況下,我們的控制器應該從父上下文中獲取 homeService Bean。

3.4. 上下文層次結構

現在我們可以將所有內容整合起來,並使用 SpringApplicationBuilder 定義上下文層次結構。

public class App {
    public static void main(String[] args) {
        new SpringApplicationBuilder()
          .parent(ParentConfig.class).web(WebApplicationType.NONE)
          .child(WebConfig.class).web(WebApplicationType.SERVLET)
          .sibling(RestConfig.class).web(WebApplicationType.SERVLET)
          .run(args);
    }
}

最後,運行 Spring Boot 應用時,我們可以通過 localhost:8074/ctx1/homelocalhost:8075/ctx2/greeting 這兩個端口訪問這兩個應用程序。

4. 結論

使用 <em >SpringApplicationBuilder</em> API,我們首先創建了應用程序兩個上下文之間的父子關係。 接下來,我們介紹瞭如何在子上下文中覆蓋父上下文的配置。 最後,我們添加了一個兄弟上下文,以演示父上下文的配置可以與其他子上下文共享。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.