Можно ли использовать Spring Boot с OSGi? Если нет, то планируете ли вы иметь OSGi Spring Boot (Apache Felix или Eclipse Equinox)? По моему мнению, облачные приложения должны быть очень модульными и обновляемыми, как это предлагает OSGi.
Можно ли использовать Spring Boot с OSGi? Если нет, то планируете ли вы иметь OSGi Spring Boot?
Ответ 1
Одной из возможностей является включение OSGi в ваше приложение загрузки Spring, чтобы некоторые части вашего приложения были доступны через фреймворк. См. fooobar.com/questions/244161/..., чтобы узнать, как вы можете запустить OSGi программно.
Но в целом нет ничего похожего на "OSGi-Support". OSGi можно интегрировать в каждое Java-приложение, и, наоборот, вы можете упаковать каждый Java-код (также ваше приложение Spring -Boot) в пакет OSGi, чтобы запустить его в контейнере OSGi (хотя, вероятно, он не будет имеют смысл вообще).
Ответ 2
На самом деле существует множество веских причин для развертывания Spring Boot в OSGi, главным из которых является производительность, особенно производительность при запуске, если ваша служба загрузки Spring - это функциональная служба (т.е. она запускается, возвращает результаты, заканчивается). Приложение, которое я сейчас тестирую в бета-тестировании в Spring Начало загрузки через ~ 0,5 секунды, развернутое в Equinox против 3,5 секунд. Другими причинами могут быть интеграция с OSGi-приложением или Java EE-сервером.
Тем не менее, вы также можете запустить OSGi из Spring Boot, по соображениям производительности я бы, скорее всего, одобрил Concierge как реализацию OSGi над Felix или Equinox, просто из-за его небольшого размера (если вашему приложению не нужны все функции более крупные реализации.
Другой альтернативой было бы обернуть библиотеки Spring, используемые вашим приложением Spring для загрузки в MSF4J (из WSO2). Это не займет много времени и может дать вам 10-кратный более быстрый запуск с 1/10-м использованием памяти.
Ответ 3
Да, есть возможность запускать приложения Spring Boot
в контейнере OSGI.
Прежде всего, вам придется перейти от упаковки jar
Spring Boot к bundle
OSGI.
Если вы используете Maven
вы можете использовать org.apache.felix:maven-bundle-plugin
для этого. Как Spring Boot
банки зависимостей не являются допустимыми OSGI
расслоения, мы должны либо сделать их действительные связки с bnd
инструмента или мы можем встроить их в сам пакет. Это можно сделать с помощью конфигурации maven-bundle-plugin
, особенно с помощью <Embed-Dependency>
.
Однако нам нужно как-то запустить пакет с приложением Spring Boot
. Идея состоит в том, чтобы запустить Spring Boot в BundleActivator
:
@Import(AppConfig.class)
@SpringBootConfiguration
@EnableAutoConfiguration
public class SpringBootBundleActivator implements BundleActivator {
ConfigurableApplicationContext appContext;
@Override
public void start(BundleContext bundleContext) {
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
appContext = SpringApplication.run(SpringBootBundleActivator.class);
}
@Override
public void stop(BundleContext bundleContext) {
SpringApplication.exit(appContext, () -> 0);
}
}
Вы также должны установить загрузчик классов контекста на загрузчик классов OSGI, загружающий пакет с помощью Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
, Это необходимо, потому что Spring
использует контекстный загрузчик классов.
Вы можете увидеть это в действии в моем демо репо: https://github.com/StasKolodyuk/osgi-spring-boot-demo
Ответ 4
Spring boot - типичные приложения для весенней загрузки, немного "толстые" для osgi... если вы используете стартовую сеть или майку, вам нужно добавить какую-то схему определения порта, так как порты являются общими для всех osgi " services "система, на которой живет среда выполнения osgi.
Причина, по которой я бы порекомендовал избегать весенней загрузки, если вы не можете уменьшить ее, заключается в том, что созданная вами весенняя загрузочная фляга /war запускает загрузчик подкласса. Это не упрощает ситуацию, когда вы запутываетесь в стандартных проблемах загрузчика классов osgi (com.whwhat.someobject.MyClass не одинаковы в разных пакетах и загрузчиках классов, поскольку они не "импортируются" из одного пакета, который экспортируется во все остальные) если есть какие-либо требования к межсетевой связи.
Я бы посоветовал придерживаться следующих руководств, чтобы сократить "ядро весенней загрузки", если таковое существует, вам не нужен веб-прослушиватель и избегать всех межсетевых сервисных интерфейсов, которые используют любые объекты, которые не являются частью стандартного импорта (например, базовый Java се классы и т.д..). Вы заботитесь только о жизненном цикле, верно?
Ответ 5
Думаю, стоит публиковать отдельный ответ (не все читают все комментарии к ответам).
Отличное решение от @StasKolodyuk дает возможность запускать приложение Spring Boot в среде OSGI.
Но с ограничением: автоматическое сопоставление Spring Boot по аннотациям не работает из-за отсутствия поддержки сканирования пакетов при запуске в OSGI.
Вот еще один трюк, который наконец позволяет приложению Spring Boot с компонентами автоматически извлекаться из вашего кода для запуска в OSGI (я тестировал в Karaf).
Функциональный пример доступен по адресу https://github.com/dimmik/osgi-spring-boot-demo.
Хитрость заключается в предоставлении соответствующего ResourcePatternResolver экземпляру SpringApplication:
package by.kolodyuk.osgi.springboot;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.osgi.io.OsgiBundleResourcePatternResolver;
@SpringBootApplication
public class SpringBootBundleActivator implements BundleActivator {
ConfigurableApplicationContext appContext;
@Override
public void start(BundleContext bundleContext) {
// Set context classloader (main trick, to enable SpringBoot start at the first place)
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
// trick to enable scan: get osgi resource pattern resolver
OsgiBundleResourcePatternResolver resourceResolver = new OsgiBundleResourcePatternResolver(bundleContext.getBundle());
// and provide it to spring application
appContext = new SpringApplication(resourceResolver, SpringBootBundleActivator.class).run();
}
@Override
public void stop(BundleContext bundleContext) {
SpringApplication.exit(appContext, () -> 0);
}
public static void main(String[] args) {
SpringApplication.run(SpringBootBundleActivator.class);
}
}
Ответ 6
Нет, он не поддерживает OSGi. Spring Загрузка предназначена для создания микросервисов в виде упакованных приложений со всеми зависимостями и даже с контейнерами сервлетов, упакованными в исполняемый JAR, поэтому он очень модульный и обновляемый, без необходимости предоставления и настройки контейнера OSGi.