5

I am using jersey to inject POJOs on various locations. Here is my config:

 register(new AbstractBinder() {
        @Override
        protected void configure() {
            bind(Bar.class).to(Bar.class).in(Singleton.class);
            bindFactory(FooFactory.class).to(Foo.class).in(Singleton.class);
            ...
        }
    });

FooFactory:

public class FooFactory implements Factory<Foo> {
    @Override
    public Foo provide() {
        return Foo.newInstance();
    }
}

Injecting into a resource works:

@Path("/myresource")
public class MyResource{
     @Inject
     protected Bar instance;
}

But

public class Foo {
     @Inject
     protected Bar instance;
}

does not. Foo.instance is null. Why? And how to make it work?

gorootde
  • 4,003
  • 4
  • 41
  • 83

1 Answers1

5

Your factory is creating Foo, so the DI framework won't attempt any more injections. You need to either let the DI framework create instances of Foo or handle the injection yourself in FooFactory.

Your FooFactory could, for example, have a Bar field, which it uses to initialise Foo with...

public class FooFactory implements Factory<Foo> {
    private final Bar theBar;

    @Inject
    public FooFactory(Bar bar) {
        theBar = bar;
    }

    @Override
    public Foo provide() {
        return Foo.newInstance(bar);
    }
}
sisyphus
  • 6,174
  • 1
  • 25
  • 35
  • Or you can inject the `ServiceLocator` into the `FooFactory`, and inject the `Foo` instance yourself. `locator.inject(fooInstance);` – Paul Samsotha Feb 01 '16 at 09:43
  • Thanks a lot! But how to know? I have not found any documentation about this on the HK2 website. Is there any? – gorootde Feb 01 '16 at 09:49
  • See also [Inject not working for nested objects](http://stackoverflow.com/q/34599145/2587435) – Paul Samsotha Feb 01 '16 at 09:53
  • 1
    This seems quite complicated, as I now have to additionally worry about how my class is beeing instantiated. Basically that means searching the whole project to determine whether my object is instantiated by a factory or not - and based on that decide if my `@Inject` will work or not. – gorootde Feb 01 '16 at 09:56
  • 1
    DI doesn't give you a magic bullet solution to object creation. It just allows you to separate object creation from object use. Also, when you tell your DI framework that it should use a Factory to create an object then you're basically telling the framework that you're in charge of creating that object. – sisyphus Feb 01 '16 at 09:58
  • Usually you write classes that are reusable, so the one implementing the class `Foo` might be another person than the one using it (with a factory). – gorootde Feb 01 '16 at 10:02
  • What's complicated here is that the Bar class is a Singleton (Gang-of-Four style), which requires some kind of injection. If it was refactored so that DI could create and manage the single instance (just using a constructor and @Singleton scope) then you wouldn't need all the Factory hoop-jumpery. – sisyphus Feb 01 '16 at 10:26