I have a class:
public class FizzBuzz {
@Named("Red") private String redService;
public static void main(String[] args) {
GuiceTest testApp = new GuiceTest();
testApp.run();
}
private void run() {
Injector inj = Guice.createInjector(new MyModule());
redService = (String)inj.getInstance(String.class);
// Should print "red-service" but is instead an empty string!
System.out.println("redService = " + redService);
}
// ... Rest of class omitted for brevity
}
public class MyModule extends AbstractModule {
@Override
protected void configure() {
bind(String.class).annotatedWith(Names.named("Red")).toInstance("red-service");
}
}
In my module I instruct Guice to bind all String.class instances @Named "Red" to the string instance "red-service", however I'm not seeing that in the outputted print statement. How am I using Guice incorrectly?
Let me just summarize some of the comments already made here ...
@Inject AnnotationFizzFuzz. Use the static main method to bootstrap your App (not run()). bindConstant.Ths brings you to something like this:
public class FizzFuzz {
@Inject
@Named("red")
private String service;
public static void main(String[] args) {
FizzFuzz fizzFuzz = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
bindConstant().annotatedWith(Names.named("red")).to("red-service");
}
}).getInstance(FizzFuzz.class);
System.out.println(fizzFuzz.service);
}
}
You've forgotten @Inject before @Named("Red").
Also using bindConstant() is prefferable for such things.
P.S. why do you receive String from inj instead of FizzBuzz?
It should be more pretty with my way.
Create first your annotation
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectSetting {
String value();
}
Create your guice module
@Slf4j
public class SettingModule extends AbstractModule {
private final Properties properties;
private SettingModule(Properties properties) {
this.properties = properties;
}
@Override
protected void configure() {
binder().bindListener(Matchers.any(), listener(((type, encounter) -> {
for (Field field : type.getRawType().getDeclaredFields()) {
if (field.isAnnotationPresent(InjectSetting.class)) {
field.setAccessible(true);
encounter.register(injector(instance -> {
try {
Object value = properties.get(
field.getAnnotation(InjectSetting.class).value());
field.set(instance, parse(value, field));
} catch (IllegalAccessException e) {
binder().addError(e);
}
}));
}
}
})));
}
TypeListener listener(BiConsumer<TypeLiteral<?>, TypeEncounter<?>> consumer) {
return consumer::accept;
}
MembersInjector<Object> injector(Consumer<Object> consumer) {
return consumer::accept;
}
Object parse(Object value, Field field) {
Type type = field.getType();
if(type == boolean.class)
value = Boolean.parseBoolean(value.toString());
else if(type == int.class)
value = Integer.parseInt(value.toString());
return value;
}
public static Module of(String propertiesPath, String... more) {
Properties properties = new Properties();
try {
properties.load(Files.newInputStream(Paths.get(propertiesPath, more)));
} catch(Exception e) {
log.error("can't load config file {}", propertiesPath);
throw new RuntimeException(e);
}
return new SettingModule(properties);
}
}
And then inject your field
@InjectSetting("database.port")
private int port;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With