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
我认为值得将其发布为单独的答案(并非每个人都阅读答案的所有注释)。
@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)
一种可能性是将OSGi嵌入到Spring Boot Application中,以便通过框架访问应用程序的某些部分.请参阅/sf/answers/327173311/以了解如何以编程方式启动OSGi.
但总的来说,没有什么比"OSGi-Support"更像了.OSGi可以集成到每个Java应用程序中,反之亦然,您可以将每个Java代码(也是您的Spring-Boot应用程序)打包到一个OSGi包中,以便在OSGi容器中启动它(尽管它可能不会太多感觉到了).
小智 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倍.
不,它不支持 OSGi。Spring Boot 的目标是将微服务创建为具有每个依赖项的打包应用程序,甚至将 servlet 容器打包在可执行 JAR 中,因此它具有高度模块化和可更新性,无需提供和配置 OSGi 容器。
| 归档时间: |
|
| 查看次数: |
13033 次 |
| 最近记录: |