Usually I define logger like this:
private static final Logger logger = LoggerFactory.getLogger(MyClass.class);
But when using @Inject
we must use non-static and non-final field, like:
@Inject
private Logger logger;
i.e. logger will be created in each instance of this class, also logger is mutable. May be exist some way to make logger static? Also how I can bind logger to certain class (I use send the class object when creating logger object from factory LoggerFactory.getLogger(MyClass.class);
, how to create logger in same way using injecting ? )?
Using GuiceIn each of your constructors that need to have something injected in them, you just add an @Inject annotation and that tells Guice to do it's thing. Guice figures out how to give you an Emailer based on the type. If it's a simple object, it'll instantiate it and pass it in.
In Guice, the @Inject annotation will be used to define setter-based as well as constructor-based dependency injection. An instance of this class is utilized to send notifications by means of the accessible correspondence services.
Guice comes with a built-in binding annotation @Named that takes a string: public class RealBillingService implements BillingService { @Inject public RealBillingService(@Named("Checkout") CreditCardProcessor processor, TransactionLog transactionLog) { ... }
Please check the Custom Injections on Guice wiki, there is a complete Log4J example.
EDIT: You can use either a static
field or a final
field for your logger, but not a static final
one. This is a Java limitation.
Also be wary that:
Injecting final fields is not recommended because the injected value may not be visible to other threads.
Haven't tested that but the code in the article should work fine for static fields, although you could improve it by getting rid of MembersInjector and doing all of it in the TypeListener (since a static field needs to be set only once).
Using requestStaticInjection()
will force you to list all your classes in a module file - not a good idea, as you will soon forget to add one.
OTOH if you just want to support JUL you might be better of using the built-in support (as mentioned by Jeff, I assumed you didn't want a general answer, since you didn't mention JUL specifically in your question).
When designing your application for dependency injection, typically the best practice is to avoid static fields and methods as much as possible. This is so that your dependencies are clearer, and so it's easier to replace your real dependencies with other instances during tests and as your application evolves. The ideal behavior, therefore, is to avoid static methods and fields (including loggers) as much as possible.
Guice, however, does allow for marking fields static, and requesting injection of static fields when the Injector is created. The fields will need to remain mutable--final
doesn't mean "final except for Guice".
public class YourClass {
@Inject static Logger logger;
/* ... */
}
public class YourModule extends AbstractModule {
@Override public void configure() {
/* YourClass.logger will work once you create your Injector. */
requestStaticInjection(YourClass.class);
}
}
Guice automatically provides java.util.logger.Logger
instances for you with the class name embedded into it, but that's only because of a special case coded into Guice. If you want a special logger, as in this SO question, you'll need to investigate the Custom Injections to which Jakub linked--but if the whole goal is to centralize logger creation so you can control it in one place, you can just refactor that into a static factory outside of Guice too.
@LogToFile
public class YourClass {
private static final Logger logger = YourLoggerFactory.create(YourClass.class);
/* ... */
}
public class YourLoggerFactory {
private YourLoggerFactory { /* do not instantiate */ }
public Logger create(Class<?> clazz) {
if (clazz.getAnnotation(LogToFile.class) != null) {
return someImplementation(new File(...));
} else {
return someOtherImplementation();
}
}
}
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