Статьи

Spring Boot и иерархия контекста приложения

Spring Boot поддерживает простой способ задания иерархии контекста приложения Spring .

Этот пост просто демонстрирует эту функцию, но я еще не нашел ее в проектах, над которыми я работал. Spring Cloud использует эту функцию для создания контекста начальной загрузки, в котором при необходимости загружаются свойства с внешнего сервера конфигурации, который впоследствии становится доступным для основного контекста приложения.

Чтобы быстро сделать шаг назад, Spring Application Context управляет жизненным циклом всех bean-компонентов, зарегистрированных в нем. Иерархии контекста приложения предоставляют способ повторного использования bean-компонентов, bean-компоненты, определенные в родительском контексте, доступны в дочерних контекстах.

Рассмотрим надуманный вариант использования нескольких контекстов приложения и иерархии контекста приложения – это должно обеспечить два разных порта с различным набором конечных точек на каждом из этих портов.

Child1 и Child2 – это типичные Spring Boot Applications, такие как:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
package child1;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import root.RootBean;
 
@SpringBootApplication
@PropertySource("classpath:/child1.properties")
public class ChildContext1 {
 
    @Bean
    public ChildBean1 childBean(RootBean rootBean, @Value("${root.property}") String someProperty) {
        return new ChildBean1(rootBean, someProperty);
    }
}

Каждое из приложений находится в своем собственном корневом пакете, чтобы избежать коллизий при сканировании bean-компонентов. Обратите внимание, что bean-компонент в дочерних контекстах зависит от bean-компонента, который ожидается из корневого контекста.

Порт для прослушивания предоставляется в качестве свойств, поскольку ожидается, что два контекста будут прослушивать разные порты. Я явно указал файл свойств для загрузки с содержимым в этих строках:

1
2
server.port=8080
spring.application.name=child1

Учитывая эту настройку, Spring Boot предоставляет гибкий интерфейс для загрузки корневого контекста и двух дочерних контекстов:

1
2
3
4
5
6
7
SpringApplicationBuilder appBuilder =
       new SpringApplicationBuilder()
               .parent(RootContext.class)
               .child(ChildContext1.class)
               .sibling(ChildContext2.class);
 
ConfigurableApplicationContext applicationContext  = appBuilder.run();

Контекст приложения, возвращаемый SpringBootApplicationBuilder, кажется последним в цепочке, определенной через ChildContext2 выше.

Если приложение теперь запущено, существует корневой контекст с двумя разными дочерними контекстами, каждый из которых предоставляет конечную точку через другой порт. Визуализация через конечную точку привода / beans показывает это:

Однако не все чисто, в консоли отображаются ошибки, связанные с экспортом конечных точек jmx, однако они носят информационный характер и не влияют на запуск.

Образцы доступны в моем репозитории github

Ссылка: Spring Boot и Иерархия контекста приложения от нашего партнера JCG Биджу Кунджуммена из блога all and sundry.