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