I'm trying to understand Jersey 2 development and context-dependency injection.
I don't understand how to inject into a resource an object that needs initialization parameters in the constructor. For example: I'd like to @Inject slf4j Logger, built using LoggerFactory.
My resource class is:
@Path("/myresource")
public class MyResource {
@Inject
private Logger log;
@GET
@Produces(MediaType.APPLICATION_JSON)
public Answer status() {
log.info("STATUS");
return new Answer(200, "Server up and running @ "+ ZonedDateTime.now());
}
}
My Resource config is:
public class MyAppextends ResourceConfig {
public MyApp() {
register(new MyBinder());
packages(true, "my.packages");
}
}
public class MyBinder extends AbstractBinder {
@Override
protected void configure() {
bindFactory(MyLoggerFactory.class).to(org.slf4j.Logger.class);
}
}
Finally, the Factory is:
public class MyLoggerFactory implements Factory<Logger> {
@Override
public Logger provide() {
return LoggerFactory.getLogger(TYPE_FOR_LOGGING.class);
}
@Override
public void dispose(Logger logger) {
}
}
How can I specify TYPE_FOR_LOGGING as argument, in order to Inject the correctly initialized Logger in every resource I want?
Thanks
What you are looking for is called the InstantiationService. You can inject it into Factories to find out who is calling the factory inside of the provide method.
Below find a code sample from the hk2 tests that illustrate the use of the InstantiationService.
@Singleton
public class CorrelationFactory implements Factory<PerLookupServiceWithName> {
private final static PerLookupServiceWithName NULL_SERVICE = new PerLookupServiceWithName() {
@Override
public String getName() {
return null;
}
};
@Inject
private InstantiationService instantiationService;
/* (non-Javadoc)
* @see org.glassfish.hk2.api.Factory#provide()
*/
@Override @PerLookup
public PerLookupServiceWithName provide() {
InstantiationData data = instantiationService.getInstantiationData();
if (data == null) {
return NULL_SERVICE;
}
Injectee parent = data.getParentInjectee();
if (parent == null) {
return NULL_SERVICE;
}
Class<?> parentClass = parent.getInjecteeClass();
if (parentClass == null) {
return NULL_SERVICE;
}
Correlator correlator = parentClass.getAnnotation(Correlator.class);
if (correlator == null) {
return NULL_SERVICE;
}
final String fName = correlator.value();
return new PerLookupServiceWithName() {
@Override
public String getName() {
return fName;
}
};
}
/* (non-Javadoc)
* @see org.glassfish.hk2.api.Factory#dispose(java.lang.Object)
*/
@Override
public void dispose(PerLookupServiceWithName instance) {
// DO nothing
}
}