If you're going to use the @Context
annotation, really all you need to do is implement a Factory<T>
parameterized by the type you want to inject. You can even inject other standard injectable objects into the Factory
, for instance HttpServletRequest
, ContainerRequestContext
, HttpHeaders
among others. For example, to match what's going on in your example above
import java.util.List;
import java.util.Locale;
import javax.inject.Inject;
import javax.ws.rs.core.HttpHeaders;
import org.glassfish.hk2.api.Factory;
public class LocaleFactory implements Factory<Locale> {
private final HttpHeaders headers;
@Inject
public LocaleFactory(HttpHeaders headers) {
this.headers = headers;
}
@Override
public Locale provide() {
List<Locale> acceptableLanguges = headers.getAcceptableLanguages();
if (acceptableLanguges.isEmpty()) {
return Locale.US;
}
if ("*".equals(acceptableLanguges.get(0).toString())) {
return Locale.US;
}
return acceptableLanguges.get(0);
}
@Override
public void dispose(Locale t) { /* Do nothing */ }
}
Then you need to bind the factory. For example in your ResourceConfig
. You can set the scope there, as in the getScope()
in your example. There is currently support for Singleton
, RequestScoped
and PerLookup
(which is default if not specified)
@ApplicationPath("/api")
public class AppConfig extends ResourceConfig {
public AppConfig() {
packages("packages.to.scan");
register(new AbstractBinder(){
@Override
public void configure() {
bindFactory(LocaleFactory.class).to(Locale.class)
.in(RequestScoped.class);
}
});
}
}
If you are using a web.xml, then you can create a Feature
and register the AbstractBinder
there, as seen here
After this, you can just inject it
@GET
public Response getLocale(@Context Locale locale) {
If you want to use a custom annotation, then you will need to implement an InjectionResolver
for the custom annotation. You can see a complete example here, and read more in the Jersey documentation - Defining Custom Injection Annotation