symon
symon

Reputation: 650

What is actually involved in a mvp scenario to use google guice?

I am very familiar with using spring to inject using @Bean & @Autowired. I have switched over to looking at guice and I am wondering what is the minimum involved to have it functioning. The following basic example throws a NPE:

import javax.inject.Inject;

public class ClassA {

    String a = "test";

    @Inject
    public ClassA() {
        System.out.println(a);
    }

    public void go() {
        System.out.println("two");
    }
}

The following class attempting to instantiate a new instance of ClassA:

import javax.inject.Inject;

public class ClassB {

    @Inject
    ClassA guice;

    public ClassB() {
        guice.go();
    }

    public static void main(String[] args) {
        ClassB b = new ClassB();
    }

}

I have tried all sorts of combinations of the following with no success:

public class SupportModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(ClassA.class);
        //bind(ClassA.class).to(ClassB.class);
        //others too

    }
}

I must be missing a key thing somewhere here, I'm not quite sure where? do I need some manual instantiation of guice/configuration itself? I assume I possibly do.

guice.go(); <= NullPointerException occurs here, obviously the obj is null because my guice setup isn't right

In Spring i can do the following, I assume Guice can aid me in doing this too:

@Bean
public FrameworkProperties properties() {
    return new FrameworkProperties();
}

and then just:

@Autowired
FrameworkProperties props;

Upvotes: 0

Views: 66

Answers (1)

Harish
Harish

Reputation: 1441

do I need some manual instantiation of guice/configuration itself? I assume I possibly do.

Yes, you assumed right. You'll have to bootstrap the Injector modules that you have defined using the Guice.createInjector() method. Also, one other thing to note is when using a custom defined constructor like in ClassB, you'll have to use constructor injection. So in order to get this working, ClassB should look like:

public class ClassB {

    private ClassA guice;

    @Inject //This will inject the dependencies used in the constructor arguments
    public ClassB(final ClassA guice) {
        this.guice = guice;
        guice.go();
    }

    public static void main(String[] args) {
        /**
         * If only type to type binding is required, you can skip creating a Module class &
         * bootstrap the injector with empty argument createInjector like used below. But, when
         * there are other kind of bindings like Type to Implementations defined in modules, you can use:
         * final Injector injector1 = Guice.createInjector(new GuiceModule1(), new GuiceModule2());
         */
        final Injector injector = Guice.createInjector();
        final ClassB b = injector.getInstance(ClassB.class); //This will create dependency graph for you and inject all dependencies used by ClassB and downwards
    }
}

Also, you can remove the @Inject annotation used in ClassA's constructor as you are not injecting any external dependencies in that constructor. You can look up the Guice's getting started wiki for more documentation.

Upvotes: 1

Related Questions