2017-06-17 8 views
1

Ich bin kürzlich auf einen Code gestoßen, der sowohl @Provides als auch @Inject Annotationen auf derselben Methode verwendet. Diese Methode hat zwei nicht-primitive Parameter und einen nicht-void-Rückgabetyp.Kombination von @Provides und @Inject

Ich fragte mich, ob es Sinn macht, diese beiden im Tandem zu verwenden. Von dem, was ich sammeln/spekulieren kann, scheint es, dass @Inject verwendet wird, um die Methodenabhängigkeiten mit Guice zu konstruieren, während @Provides verwendet wird, um den Rückgabetyp zu binden. Irgendwelche Ideen würden geschätzt werden.

Antwort

6

Nein, es gibt nie einen Fall, in dem Sie @Provides und @Inject auf der gleichen Methode sehen würden.

@Inject macht Sinn auf Bauer, Methoden und Felder:

  • Auf Konstrukteure, es markiert den Konstruktor, die DI Framework nennen sollte. Das Framework stellt alle Parameterwerte zur Verfügung.
  • Bei Feldern zeigt es an, dass das DI-Framework das Feld von außerhalb festlegen sollte. Das Framework liefert den Feldwert.
  • Bei Methoden zeigt es an, dass das DI-Framework nach der Konstruktion die Methode genau einmal aufrufen sollte. Das Framework stellt die Parameterwerte bereit. Der Rückgabewert ist bedeutungslos und oft void.

Zum Beispiel:

public class YourInjectableClass { 

    // Guice will use this constructor... 
    @Inject public YourInjectableClass(YourDep dep) { /* ... */ } 
    // ...instead of this one 
    public YourInjectableClass(YourDep dep, YourOtherDep otherDep) { /* ... */ } 

    // Guice will populate this field after construction. 
    @Inject YourField yourField; 

    @Inject public void register(Registry registry) { 
    // Guice will create or get a Registry and call this method after construction. 
    // It sometimes makes sense for this to be protected or package-private, 
    // so this class's consumers aren't tempted to call it themselves. 
    } 
} 

@Provides hat einen viel engeren Zweck: Wenn in Guice-Modulen, @Provides auf Methoden geht und zeigt an, dass Guice die Methode aufrufen soll, wenn es eine Instanz des Verfahrens Bedürfnisse möglicherweise -parametrisierter Typ (und erbt die Bindungsanmerkungen oder Qualifier von der Methode selbst). Dagger hat eine ähnliche Annotation, da @Provides nicht im JSR-330 Abhängigkeitsinjektionsstandard definiert ist.

public class YourModule extends AbstractModule { 
    @Override public void configure() {) // still needed for AbstractModule 

    // Guice will call this whenever it needs a @SomeBindingAnnotation YourInstance. 
    // Because you list a YourDep as a parameter, Guice will get and pass in a YourDep. 
    @Provides @SomeBindingAnnotation YourInstance create(YourDep dep) { 
    return YourInstanceFactory.create(dep); 
    } 
} 

Folglich Sie sollten so gut wie nie, diese Anmerkungen in der gleichen Datei, geschweige denn auf der gleichen Methode. Die einzige Ausnahme ist, wenn Sie der fragwürdigen Praxis folgen, ein Modul zu erstellen, das selbst injizierbar ist (vermutlich ein injiziertes Modul von einem Injektor zu bekommen, um einen anderen Injektor zu konfigurieren), und selbst dann würden Sie sie nicht auf dieselbe Weise sehen: @Inject Methoden werden einmal aufgerufen, um Abhängigkeiten zu speichern, und @Provides Methoden sollten immer dann aufgerufen werden, wenn eine neue Instanz benötigt wird.

+0

Vielen Dank für die Klärung. Um es klar zu sagen, die mit @Inject annotierten Methoden werden nach der Konstruktion von YourInjectableClass aufgerufen, oder? – OrangeApple3

+0

@ OrangeApple3 Ja. Diese Technik wird [Methodeninjektion] genannt (https://github.com/google/guice/wiki/Injections#method-injection). –

Verwandte Themen