Рубрики
Без рубрики

Как динамически подключать боб весной

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

Автор оригинала: baeldung.

1. введение

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

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

2. Динамические Случаи использования автоматической проводки

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

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

public interface RegionService {
    boolean isServerActive(int serverId);

    String getISOCountryCode();
}

и две реализации:

@Service("GBregionService")
public class GBRegionService implements RegionService {
    @Override
    public boolean isServerActive(int serverId) {
        return false;
    }

    @Override
    public String getISOCountryCode() {
        return "GB";
    }
}
@Service("USregionService")
public class USRegionService implements RegionService {
    @Override
    public boolean isServerActive(int serverId) {
        return true;
    }

    @Override
    public String getISOCountryCode() {
        return "US";
    }
}

Допустим, у нас есть веб-сайт, на котором пользователь может проверить, активен ли сервер в выбранном регионе. Следовательно, мы хотели бы иметь класс обслуживания, который динамически изменяет реализацию интерфейса Region Service с учетом ввода пользователя . Несомненно, это тот случай использования, когда в игру вступает динамическая автоматическая проводка бобов.

3. Использование BeanFactory

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

@Service
public class BeanFactoryDynamicAutowireService {
    private static final String SERVICE_NAME_SUFFIX = "regionService";
    private final BeanFactory beanFactory;

    @Autowired
    public BeanFactoryDynamicAutowireService(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public boolean isServerActive(String isoCountryCode, int serverId) {
        RegionService service = beanFactory.getBean(getRegionServiceBeanName(isoCountryCode), 
          RegionService.class);

        return service.isServerActive(serverId);
    }

    private String getRegionServiceBeanName(String isoCountryCode) {
        return isoCountryCode + SERVICE_NAME_SUFFIX;
    }
}

Мы использовали перегруженную версию метода getBean () , чтобы получить боб с заданным именем и желаемым типом.

И хотя это работает, мы бы предпочли полагаться на что-то более идиоматичное, то есть на то, что использует инъекцию зависимостей.

4. Использование Интерфейсов

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

Помимо стандартной автопроводки с одним полем, Spring дает нам возможность собирать все компоненты, которые являются реализациями конкретного интерфейса, в Map :

@Service
public class CustomMapFromListDynamicAutowireService {
    private final Map servicesByCountryCode;

    @Autowired
    public CustomMapFromListDynamicAutowireService(List regionServices) {
        servicesByCountryCode = regionServices.stream()
                .collect(Collectors.toMap(RegionService::getISOCountryCode, Function.identity()));
    }

    public boolean isServerActive(String isoCountryCode, int serverId) {
        RegionService service = servicesByCountryCode.get(isoCountryCode);

        return service.isServerActive(serverId);
    }
}

Мы создали карту в конструкторе, который содержит реализации по коду страны. Кроме того, мы можем использовать его позже в методе, чтобы получить конкретную реализацию, чтобы проверить, активен ли данный сервер в определенном регионе.

5. Заключение

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

Как всегда, код, показанный в этой статье, доступен на GitHub .