登录
  • 欢迎访问悠扬的技术博客,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站😉

玩转OSGI-ApacheFelix(五)Springboot

Apache Felix 悠扬 842次浏览 已收录

一、Spring Boot可以和OSGi一起使用吗?

是的,可以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);
    }
}

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

相关示例代码地址:https://gitee.com/zsiyang/felix-demo

但是这样有个局限性,由于在OSGI中运行时缺少程序包扫描支持,因此Spring Boot的按批注自动映射功能不起作用。OSGI对于包开放配置粒度比较细,然后有人提出了另一种解决方案

诀窍是为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);
    }
}

另一种方案提议没有找到方案:

          实际上有很多很好的理由将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倍.

二、boot项目打包插件

     在研究时发现相关问题,有个比较头疼的东东还未完全研究,先行记录:

spring-boot-starter-parent.pom文件中  猜猜这东西最终影响了打包某些参数生成。osgi.ee=JavaSE9.0  由于插件组合进行打包,2.6.6版本更换后是1.8依赖,这里需要9的话很多引用都要变更,目前是用2.6.6进行替换测试,后面若有机会,继续研究,将更新文档内容

org.apache.maven.plugins.shade.resource.ManifestResourceTransformer

玩转OSGI-ApacheFelix(五)Springboot

Setting Manifest Entries with the ManifestResourceTransformer

The ManifestResourceTransformer allows existing entries in the MANIFEST to be replaced and new entries added.

For example, the following sample sets

  • the Main-Class entry to the value of the app.main.class property,
  • the X-Compile-Source-JDK entry to the value of the maven.compile.source property and
  • the X-Compile-Target-JDK entry to the value of the maven.compile.target property.

By default the ManifestResourceTransformer will relocate the following attributes:

  • Export-Package
  • Import-Package
  • Provide-Capability
  • Require-Capability

With additionalAttributes you can specify the attributes that need to be relocated too.

<project>
   ...
   <build>
      <plugins>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
               <execution>
                  <goals>
                     <goal>shade</goal>
                  </goals>
                  <configuration>
                     <transformers>
                        <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                           <manifestEntries>
                              <Main-Class>${app.main.class}</Main-Class>
                              <X-Compile-Source-JDK>${maven.compile.source}</X-Compile-Source-JDK>
                              <X-Compile-Target-JDK>${maven.compile.target}</X-Compile-Target-JDK>
                           </manifestEntries>
                        </transformer>
                     </transformers>
                  </configuration>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </build>
   ...
</project>

参考文献记录:

JavaFX中文资料

bndtools.org


版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明玩转OSGI-ApacheFelix(五)Springboot
喜欢 (0)
支付宝[]
分享 (0)
悠扬
关于作者:
10年以上工作经验:6年以上微服务架构设计搭建经验。 曾任岗位:项目经理、架构师。 擅长领域:大数据、数据库,架构设计,资源优化。 获得业绩: 1.实用新型发明专利1个,修改Apache Sharding源码设计实现分库分表程序增强方案。 2.开源项目一个:https://gitee.com/zsiyang/ruoyi-vue-atomikos (加入开源生态圈)。 3.个人技术博客地址:https://www.nxhz1688.com