简体   繁体   中英

How to use dependency injected fields for a static final field initialization in guice?

I have a field in a class that stores the map of objects which are injected into the class. How to populate this field?

This field will be primarily used for lookup and therefore qualifies to be a static final variable (Right?) ?

Example :

mapOfObjects.put("foo",x);
mapOfObjects.put("bar",y);

Sample Code

public class A {
    private ClassX x;
    private ClassY y;

    private final Map<String, Object> mapOfObjects = new HashMap<>();

    public void someMethod() {
        Object obj = mapOfObjects.get("x");
        //do something fancy with obj
    }

    @Inject
    public void setX(ClassX x) {
        this.x = x;
    }

    @Inject
    public void setY(ClassY y) {
        this.y = y;
    }
}
  1. Can the map construction be done in a static block? Is this method ugly?
  2. What happens first - dependency injection or static block of code?
  3. What is the best method so that this class is also testable.

Thank you.

If you want to use dependency injection, your map is not too big or your component is not necessarily stateful, then you may try Guice Multibinidngs and a non static field. You will need an extra dependency to com.google.inject.extensions:guice-multibindings because this is extension to the core guice, supporting map and set bindings.

Here is how a module defining map binding may look like:

class SampleModule extends AbstractModule
{
    @Override
    protected void configure()
    {
        MapBinder<String, Object> templatesBinder = MapBinder.newMapBinder(
                        binder(), 
                        String.class, 
                        Object.class, Names.named("MyBindings"));

        templatesBinder.addBinding("A").toInstance(1);
        templatesBinder.addBinding("B").toInstance("Hi!");
        templatesBinder.addBinding("B").toInstance(Boolean.FALSE);
    }
}

The way that you inject your map will look like this:

@Inject
@Named("MyBindings")
private Map<String, Object> cache;

If you are really concerned about the non-static nature of this you can wrap the map in a singleton component binding.

A1: Yes, it can. Not absolutely necessarily.

A2: Static block of code.

A3: Not a static block :-) The multibinders are acceptable IMO. Guice,JUnit and Mockito work very well together.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM