Динамическая внешняя конфигурация SpringBoot с файлами Jar - PullRequest
0 голосов
/ 17 октября 2019

Я ищу Руководство по правильной архитектуре этого в SpringBoot.

enter image description here В основе моего проекта у меня есть приложение SpringBoot, которое будет настроено при запускевремя через значение свойства, которое будет определенным AdapterType my.adapter.type

Для этого примера возможными значениями являются:

Modem
Turkey
Computer
Beef

На пути к классам будет существовать jar файл с пакетом: org.myapp.adapters. В этом пакете находятся различные классы Spring @Component, каждый из которых реализует интерфейс SystemAdapter, который задает type (один из перечисленных выше типов) и метод getType().

Приложение будет использовать

@ComponentScan(basePackages = {"org.myapp.adapters"})

при запуске, чтобы узнать, какие адаптеры существуют, и затем вызовет метод getType() на каждом адаптере, чтобы определить, к какому типу он относится.

Далее SystemAdapterFactory будетсопоставить значение свойства my.adapater.type с типом, возвращаемым методами getType() Бинов, возвращающих правильный адаптер для заданного указанного типа.

Цель состоит в том, чтобы обеспечить интерфейс SystemAdapter иEnum jar для других команд, которые могут написать свои собственные библиотеки SystemAdapater. Затем при запуске мы можем поменять DefaultAdapaters.jar , скажем, FoodAdapaters.jar

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

Где я сталкиваюсь с путаницей, это как на самом деле настроить Gradle и SpringBoot, чтобы делать то, что я хочу. Похоже, что задание по умолчанию bootJar компилируется в кучу файлов .class - и поэтому я не знаю, как на самом деле построить это решение.

Я думаю, мне нужно 3 отдельныхпроекты (или модули)

Application
Interface
AdapterImplementation

Я считаю, что если я использую конфигурацию загрузчика свойств в моем проекте Application:

bootJar {
    manifest {
        attributes 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher'
    }
}

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

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

Так что мои вопросы:

1) Правильный ли я подход к тому, как структурировать и, возможно, заставить это работать

2) Есть ли другой метод, который мы пропустили, который упростил бы все?

Спасибо

Ответы [ 2 ]

1 голос
/ 17 октября 2019

Я думаю, SpringBatch имеет хороший пример того, чего вы хотите достичь. Если вас устраивают значения по умолчанию SpringBatch, вы просто набираете @EnableBatchProcessing, и он будет использовать компоненты, уже указанные в вашей среде, такие как dataSource, transactionManager и т. Д.

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

package i.live.where.the.application.context.is.created;

@EnableBatchProcessing
public class BatchConfiguration extends DefaultBatchConfigurer {

    @Override
    @Autowired
    public void setDataSource(@Qualifier("batchDataSource") DataSource batchDataSource) {
        super.setDataSource(batchDataSource);
    }
}

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

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

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

package some.other.teams.module;

@Component("batchDataSource")
public class BatchDataSource implements your.module.DataSource {/*** ***/}

В сочетании с BatchConfiguration надпредоставляет разработчикам возможность менять реализации по мере необходимости.

0 голосов
/ 17 октября 2019

Мне удалось ответить на мой собственный вопрос. Я задокументировал подход, который использовал в среднем: https://medium.com/@Jeef/dynamically-loading-libraries-into-a-springboot-application-at-run-time-80639ee5aab?sk=5851d25c7106307ff0f2b0a4171ab613

Также я создал пример проекта, демонстрирующего реализацию на GitHub: https://github.com/jeeftor/SpringBoot-Dynamic-JarLoad

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...