Spring Boot可以和OSGi一起使用吗?如果没有,有没有计划进行OSGi Spring Boot?

use*_*774 18 osgi spring-boot

Spring Boot可以和OSGi一起使用吗?如果没有,任何计划有OSGi Spring Boot(Apache Felix或Eclipse Equinox)?在我看来,云应用程序必须是高度模块化的,并且可以像OSGi提供的那样进行更新.

Sta*_*yuk 12

是的,可以Spring Boot在OSGI容器中运行应用程序.

首先,您必须从Spring Boot jar包转换到OSGI bundle.

如果你正在使用,Maven你可以用它org.apache.felix:maven-bundle-plugin来做.由于Spring Boot依赖jar不是有效的OSGIbundle,我们应该使用bnd工具将它们作为有效的bundle,或者我们可以将它们嵌入到bundle本身中.这可以通过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);
    }
}
Run Code Online (Sandbox Code Playgroud)

您还应该将上下文类加载器设置为加载bundle的OSGI类加载器Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());.这是必需的因为Spring使用上下文类加载器.

你可以在我的演示仓库中看到这个:https://github.com/StasKolodyuk/osgi-spring-boot-demo


Dmi*_*sky 7

我认为值得将其发布为单独的答案(并非每个人都阅读答案的所有注释)。

@StasKolodyuk提供的出色解决方案提供了一种在OSGI环境中运行Spring Boot应用程序的方法。

但有一个局限性:由于在OSGI中运行时缺少程序包扫描支持,因此Spring Boot的按批注自动映射功能不起作用。

这是另一个技巧,它最终使带有组件的Spring Boot应用程序可以从您的代码中自动提取并在OSGI中运行(我在Karaf中进行了测试)。

有关功能示例,请访问https://github.com/dimmik/osgi-spring-boot-demo

诀窍是为SpringApplication实例提供适当的ResourcePatternResolver:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*del 6

一种可能性是将OSGi嵌入到Spring Boot Application中,以便通过框架访问应用程序的某些部分.请参阅/sf/answers/327173311/以了解如何以编程方式启动OSGi.

但总的来说,没有什么比"OSGi-Support"更像了.OSGi可以集成到每个Java应用程序中,反之亦然,您可以将每个Java代码(也是您的Spring-Boot应用程序)打包到一个OSGi包中,以便在OSGi容器中启动它(尽管它可能不会太多感觉到了).

  • 我对你的回答有疑问.您写道,每个Java代码(也是Spring-Boot应用程序)都可以打包到OSGi-bundle中,以便在OSGi容器中启动它.问题是,如何将Spring-Boot应用程序打包到OSGi-bundle中? (4认同)

小智 6

实际上有很多很好的理由将Spring Boot部署到OSGi中,主要的是性能,特别是如果你的Spring Boot服务是一个功能服务(即它启动,返回结果,结束)的启动性能.我目前在Spring Boot中进行beta测试的应用程序在部署到Equinox的约0.5秒内启动,而自行启动时为3.5秒.其他原因可能是与基于OSGi的应用程序或Java EE服务器的集成.

也就是说,你也可以从Spring Boot运行OSGi,出于性能原因,我可能会赞成将Concierge作为一个超过Felix或Equinox的OSGi实现,因为它的体积很小(除非你的应用程序需要更大实现的所有功能).

另一种方法是将Spring Boot应用程序使用的Spring库包装到MSF4J(来自WSO2).这不需要太多工作,并且可以使您的内存使用率提高10倍,启动速度提高10倍.


dun*_*nni 4

不,它不支持 OSGi。Spring Boot 的目标是将微服务创建为具有每个依赖项的打包应用程序,甚至将 servlet 容器打包在可执行 JAR 中,因此它具有高度模块化和可更新性,无需提供和配置 OSGi 容器。