Перейти к основному содержимому

Регистрация функционального компонента Spring 5

· 3 мин. чтения

1. Обзор

Spring 5 поставляется с поддержкой регистрации функциональных компонентов в контексте приложения.

Проще говоря, это можно сделать с помощью перегруженных версий нового метода registerBean() , определенного в классе GenericApplicationContext .

Давайте посмотрим на несколько примеров этой функциональности в действии.

2. Зависимости Maven

Самый быстрый способ настроить проект Spring 5 — использовать Spring Boot , добавив зависимость spring-boot-starter-parent в файл pom.xml:

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version>
</parent>

Нам также нужны spring-boot-starter-web и spring-boot-starter-test для нашего примера, чтобы использовать контекст веб-приложения в тесте JUnit :

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

Конечно, Spring Boot не нужен, чтобы использовать новый функциональный способ регистрации бина. Мы также могли бы просто добавить зависимость spring-core напрямую:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.3</version>
</dependency>

3. Регистрация функционального компонента

API registerBean() может принимать два типа функциональных интерфейсов в качестве параметров :

  • аргумент Поставщика , используемый для создания объекта
  • BeanDefinitionCustomizer vararg, который можно использовать для предоставления одного или нескольких лямбда-выражений для настройки BeanDefinition ; этот интерфейс имеет единственный метод custom()

Во-первых, давайте создадим очень простое определение класса, которое мы будем использовать для создания bean-компонентов:

public class MyService {
public int getRandomNumber() {
return new Random().nextInt(10);
}
}

Давайте также добавим класс @SpringBootApplication , который мы можем использовать для запуска теста JUnit :

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

Затем мы можем настроить наш тестовый класс, используя аннотацию @SpringBootTest для создания экземпляра GenericWebApplicationContext :

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Spring5Application.class)
public class BeanRegistrationIntegrationTest {
@Autowired
private GenericWebApplicationContext context;

//...
}

В нашем примере мы используем тип GenericWebApplicationContext , но любой тип контекста приложения может использоваться таким же образом для регистрации компонента.

Давайте посмотрим, как мы можем зарегистрировать bean-компонент, используя лямбда-выражение для создания экземпляра :

context.registerBean(MyService.class, () -> new MyService());

Давайте проверим, что теперь мы можем получить компонент и использовать его:

MyService myService = (MyService) context.getBean("com.foreach.functional.MyService"); 

assertTrue(myService.getRandomNumber() < 10);

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

context.registerBean("mySecondService", MyService.class, () -> new MyService());

Далее давайте посмотрим, как мы можем зарегистрировать bean-компонент, добавив лямбда-выражение для его настройки :

context.registerBean("myCallbackService", MyService.class, 
() -> new MyService(), bd -> bd.setAutowireCandidate(false));

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

4. Вывод

В этом кратком руководстве мы увидели, как мы можем использовать функциональный способ регистрации компонента.

Исходный код примера можно найти на GitHub .