Letzte Woche habe ich damit begonnen, eine Anwendung, die Spring für DI verwendet, auf Google Guice zu migrieren, als ich über Multibinding stolperte. Seit Google Guice 2.0 können wir Multibinding verwenden, das es uns ermöglicht, mehrere Objekte an eine Sammlung zu binden. Aber was ich in der aktuellen Version vermisst habe, ist die Möglichkeit, Objekte mit einer bestimmten Annotation zu binden. Also habe ich mir gedacht, warum nicht selbst etwas bauen :)
Verwenden wir also das Multibinder-Beispiel, das in der Javadoc von Multibinder beschrieben ist.
public class SnacksModule extends AbstractModule {
protected void configure() {
Multibinder multibinder = Multibinder.newSetBinder(binder(), ISnack.class);
multibinder.addBinding().toInstance(new Twix());
multibinder.addBinding().toProvider(SnickersProvider.class);
multibinder.addBinding().to(Skittles.class);
}
}
Mit dieser Bindung kann nun ein Set<ISnack> injiziert werden:
class SnackMachine {
@Inject
public SnackMachine(Set Snacks) { ... }
}
Das ist gut, wenn Sie nur ein paar Snacks haben, aber wenn Sie viele haben und Ihr Modul sauber und einfach halten wollen, brauchen Sie wahrscheinlich etwas wie das hier
multibind(ISnack.class).toAnnotatedClasses(Snack.class);
Wo ein Snack so aussieht:
@Snack
public class Snickers implements ISnack { ... }
Um dies zu ermöglichen, habe ich das folgende Modul erstellt:
public abstract class AbstractMultibindModule extends AbstractModule {
public AdvancedMultibinder multibind(Klasse clazz) {
return new AdvancedMultibinder(clazz);
}
public class AdvancedMultibinder {
private Multibinder multibinder;
private Class clazz;
private AdvancedMultibinder(Klasse clazz) {
this.clazz = clazz;
multibinder = Multibinder.newSetBinder(binder(), clazz);
}
public Multibinder toAnnotatedClasses(Class bindingAnnotation) {
return toAnnotatedClasses(bindingAnnotation, clazz.getPackage().getName());
}
public Multibinder toAnnotatedClasses(Class bindingAnnotation, String basePackageName) {
for (Klasse clazz : AnnotationUtil.getAnnotatedClasses(bindingAnnotation, basePackageName)) {
multibinder.addBinding().to(clazz);
}
return multibinder;
}
public LinkedBindingBuilder addBinding() {
return multibinder.addBinding();
}
}
}
Wie Sie sehen können, gibt die multibind-Methode einen AdvancedMultibinder zurück. Wir können Multibinder nicht erweitern, da es einen privaten Konstruktor hat. Stattdessen verwende ich den Multibinder intern und rufe Methoden auf, um Bindungen hinzuzufügen. Der AdvancedMultibinder hat eine Methode toAnnotatedClasses, die die Annotationsklasse als Parameter annimmt und eine Bindung für jede annotierte Klasse hinzufügt. Jetzt können wir Folgendes tun.
AdvancedMultibinder multibinder = multibind(ISnack.class); multibinder.toAnnotatedClasses(Snack.class); // Fügen Sie eine nicht-kommentierte Klasse zum Bind hinzu. multibinder.addBinding().to(Skittles.class); bind(Machine.class).to(SnackMachine.class);
Ich habe das Beispielprojekt hier angehängt, damit Sie sich den Code selbst ansehen können.
Verfasst von
Mischa Dasberg
Contact



