Integrate Guice component into Spring application
Asked Answered
B

3

10

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 done?

We came across the following links that show how integrate Spring into Guice, but we need it the other way around:

http://google-guice.googlecode.com/git/javadoc/com/google/inject/spring/SpringIntegration.html

http://www.jroller.com/mindcrime/entry/an_example_of_integrating_guice

Any help is appreciated

Bulla answered 16/9, 2013 at 10:58 Comment(0)
S
5

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.

Syndesis answered 10/9, 2019 at 4:25 Comment(0)
G
1

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).

Glove answered 1/2, 2016 at 16:26 Comment(0)
C
-1

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

Cythiacyto answered 16/9, 2014 at 2:17 Comment(1)
This is not very helpful. How about all these multibinders, providers etc.?Frutescent

© 2022 - 2024 — McMap. All rights reserved.