Can Spring Boot be used with OSGi? If not, any plans to have an OSGi Spring Boot?

前端 未结 7 1269
闹比i
闹比i 2021-01-31 17:28

Can Spring Boot be used with OSGi? If not, any plans to have an OSGi Spring Boot (Apache Felix or Eclipse Equinox)? In my opinion, cloud applications must be highly modular and

7条回答
  •  有刺的猬
    2021-01-31 17:48

    I think it worth posting as separate answer (not everyone reads all comments to answers).

    Excellent solution from @StasKolodyuk gives a way to run Spring Boot application in an OSGI environment.

    But with limitation: Spring Boot's auto-mapping by annotation does not work because of lack of package scan support when run in OSGI.

    Here is another trick, that finally allows Spring Boot app with components to be auto-taken from your code to be run in OSGI (I tested in Karaf).

    Functional example is available at https://github.com/dimmik/osgi-spring-boot-demo

    The trick is to provide appropriate ResourcePatternResolver to SpringApplication instance:

    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);
        }
    }
    

提交回复
热议问题