![JAR search and dependency download from the Maven repository](/logo.png)
com.netflix.governator.providers.AdvisesBinder Maven / Gradle / Ivy
package com.netflix.governator.providers;
import com.google.inject.Binder;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.binder.LinkedBindingBuilder;
import com.google.inject.util.Types;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.function.UnaryOperator;
/**
* AdvisesBinder is a Guice usage pattern whereby a provisioned object may be modified or even
* replaced using rules specified as bindings themselves. This customization is done before the
* provisioned object is injected. This functionality is useful for frameworks that wish to provide
* a default implementation of a type but allow extensions and customizations by installing modules
* with AdvisesBinder.bindAdvice() bindings.
*
* {@link Module} method annotations {@literal @}{@link ProvidesWithAdvice} and {@literal @}{@link Advises}
* may be used instead of calling AdvisesBinder directly.
*
* For example,
*
*
* {@code
static class AdviseList implements UnaryOperator{@literal <}List{@literal <}String{@literal >}{@literal >} {
@Override
public List{@literal <}String{@literal >} apply(List{@literal <}String{@literal >} t) {
t.add("customized");
return t;
}
}
public static class MyModule extends AbstractModule() {
TypeLiteral{@literal <}List{@literal <}String{@literal >}{@literal >} LIST_TYPE_LITERAL = new TypeLiteral{@literal <}List{@literal <}String{@literal >}{@literal >}() {};
@Override
protected void configure() {
install(AdvisableAnnotatedMethodScanner.asModule());
AdvisesBinder.bind(binder(), LIST_TYPE_LITERAL).toInstance(new ArrayList{@literal <}{@literal >}());
AdvisesBinder.bindAdvice(binder(), LIST_TYPE_LITERAL, 0).to(AdviseList.class);
}
});
}
*
* will add "customized" to the empty list. When List<String> is finally injected it'll have
* ["customized"].
*
* Note that AdvisesBinder can be used with qualifiers such as {@literal @}Named.
*/
public abstract class AdvisesBinder {
private AdvisesBinder() {
}
public static LinkedBindingBuilder bind(Binder binder, TypeLiteral type) {
return newRealAdvisesBinder(binder, Key.get(type));
}
public static LinkedBindingBuilder bind(Binder binder, Class type) {
return newRealAdvisesBinder(binder, Key.get(type));
}
public static LinkedBindingBuilder bind(Binder binder, TypeLiteral type, Annotation annotation) {
return newRealAdvisesBinder(binder, Key.get(type, annotation));
}
public static LinkedBindingBuilder bind(Binder binder, Class type, Annotation annotation) {
return newRealAdvisesBinder(binder, Key.get(type, annotation));
}
public static LinkedBindingBuilder bind(Binder binder, TypeLiteral type, Class extends Annotation> annotationType) {
return newRealAdvisesBinder(binder, Key.get(type, annotationType));
}
public static LinkedBindingBuilder bind(Binder binder, Key key) {
return newRealAdvisesBinder(binder, key);
}
public static LinkedBindingBuilder bind(Binder binder, Class type, Class extends Annotation> annotationType) {
return newRealAdvisesBinder(binder, Key.get(type, annotationType));
}
static Key getAdvisesKeyForNewItem(Binder binder, Key key) {
binder = binder.skipSources(AdvisesBinder.class);
Annotation annotation = key.getAnnotation();
String elementName = key.hasAttributes() ? key.getAnnotation().toString() : "";
AdviceElement element = new AdviceElementImpl(elementName, AdviceElement.Type.SOURCE, 0);
Key uniqueKey = Key.get(key.getTypeLiteral(), element);
// Bind the original key to a new AdvisedProvider
binder.bind(key).toProvider(new AdvisedProvider(key.getTypeLiteral(), element.name(), annotation, binder.getProvider(uniqueKey)));
return uniqueKey;
}
static LinkedBindingBuilder newRealAdvisesBinder(Binder binder, Key key) {
Key uniqueKey = getAdvisesKeyForNewItem(binder, key);
return binder.bind(uniqueKey);
}
public static LinkedBindingBuilder> bindAdvice(Binder binder, TypeLiteral type, int order) {
return newRealAdviceBinder(binder, Key.get(type), order);
}
public static LinkedBindingBuilder> bindAdvice(Binder binder, Class type, int order) {
return newRealAdviceBinder(binder, Key.get(type), order);
}
public static LinkedBindingBuilder> bindAdvice(Binder binder, TypeLiteral type, Annotation annotation, int order) {
return newRealAdviceBinder(binder, Key.get(type, annotation), order);
}
public static LinkedBindingBuilder> bindAdvice(Binder binder, Class type, Annotation annotation, int order) {
return newRealAdviceBinder(binder, Key.get(type, annotation), order);
}
public static LinkedBindingBuilder> bindAdvice(Binder binder, TypeLiteral type, Class extends Annotation> annotationType, int order) {
return newRealAdviceBinder(binder, Key.get(type, annotationType), order);
}
public static LinkedBindingBuilder> bindAdvice(Binder binder, Key key, int order) {
return newRealAdviceBinder(binder, key, order);
}
public static LinkedBindingBuilder> bindAdvice(Binder binder, Class type, Class extends Annotation> annotationType, int order) {
return newRealAdviceBinder(binder, Key.get(type, annotationType), order);
}
@SuppressWarnings("unchecked")
static Key> getAdviceKeyForNewItem(Binder binder, Key key, int order) {
binder = binder.skipSources(AdvisesBinder.class);
String elementName = key.hasAttributes() ? key.getAnnotation().toString() : "";
@SuppressWarnings("unused")
Annotation annotation = key.getAnnotation();
Type adviceType = Types.newParameterizedType(UnaryOperator.class, key.getTypeLiteral().getType());
return (Key>) Key.get(adviceType, new AdviceElementImpl(elementName, AdviceElement.Type.ADVICE, order));
}
static LinkedBindingBuilder> newRealAdviceBinder(Binder binder, Key key, int order) {
Key> uniqueKey = getAdviceKeyForNewItem(binder, key, order);
return binder.bind(uniqueKey);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy