Integrate Guice component into Spring application

前端 未结 3 582
鱼传尺愫
鱼传尺愫 2021-01-11 21:20

We have a Spring framework based application and need to integrate a component that is built using Google Guice.

Can anybody give us some advice on how this can be

相关标签:
3条回答
  • 2021-01-11 22:10

    Have a look at the spring-guice project. In particular see the information on accessing modules. I haven't tried it since its not released but I have contemplated copying some of the code.

    The way I have done this in the paste is to just let the Guice components be powered by Guice and retrieve them in either in Spring's Java Config (@Bean) using Guice directly or use a nasty static service locator pattern (ie static method to retrieve component dynamically from Guice).

    The biggest problem I have had regardless of approach is figuring out what boots first since you have competing lifecycles (in theory the spring-guice project would fix this).

    0 讨论(0)
  • 2021-01-11 22:11

    No Special framework or dependency is required to integrate guice component into spring-boot.

    standard boot app

        @SpringBootApplication
        public class App {
           SpringApplication.run(App.class, appArgs);
        }
    

    Guice module config

      @Configuration
      public class GuiceBeanConfig {
    
        private final Injector injector;
    
        // guice modules are initialized before the spring context completes 
        {
            injector = Guice.createInjector(
                    new MyModuleA(),
                    new MyModuleB()
            );
        }
    
        /**
         * Option1: can expose injector as a Spring Bean.
         */
        @Bean
        public Injector injector() {
            return injector;
        }
    
    
        /**
         * Option2: expose specific component as a Spring Bean.
         */
        @Bean
        public MyServiceA serviceA() {
            return injector.getInstance(ServiceA.class);
        }
    }
    

    Autowire into your service component as a regular spring bean.

    • Option1: autowire guice injector and access any bean from it

       @Service
       public class MySpringService {
      
          private final ServiceA serviceA;  
      
          MySpringService (Injector i){
             serviceA = injector.getInstance(ServiceA.class)
          }
      
          public void callServiceA() {
              serviceA.doSomething();
          }
      
        }
      
    • Option2: autowire specific bean

      @Service
      public class MySpringService {
      
        private final ServiceA serviceA; 
      
        MySpringService (ServiceA s){
            serviceA = s;
        }
      
        public void callServiceA() {
            serviceA.doSomething();
        }
      
      }
      

    NOTE 1: By default Spring uses scope: Singleton and guice: Prototype. In case your guice component is not annotated as @Singleton :
    Option1 creates an instance of ServiceA each time you create a new instance of MySpringService.
    Option2 instead exposes ServiceA as a bean with scope Singleton.

    Singleton vs Prototype: if you component/service is threadsafe, does not keep state the better option would be Singleton. Much better performance, less work for GC.

    NOTE 2: Spring-boot does not require to use @Autowire annotation in case you do constructor injection.

    0 讨论(0)
  • 2021-01-11 22:20

    Both Spring and Guice support JSR 330: Dependency Injection for Java. If the Guice component you need is defined using JSR 330 annotations, or if you have access to the code an can change the annotations, then you should be able to use it in an Spring managed bean.

    See Spring: Using JSR 330 Standard Annotation and Guice JSR-330 Integration

    0 讨论(0)
提交回复
热议问题