Created
May 25, 2016 14:10
-
-
Save psamsotha/838a194f883438faee2037e2baabe6c6 to your computer and use it in GitHub Desktop.
Nested injection with Jersey/HK2 (Stackoverflow http://stackoverflow.com/q/37431802/2587435)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.annotation.ElementType; | |
import java.lang.annotation.Retention; | |
import java.lang.annotation.RetentionPolicy; | |
import java.lang.annotation.Target; | |
import java.lang.reflect.Type; | |
import java.util.logging.Logger; | |
import javax.inject.Inject; | |
import javax.inject.Named; | |
import javax.inject.Singleton; | |
import javax.ws.rs.GET; | |
import javax.ws.rs.Path; | |
import javax.ws.rs.core.Response; | |
import org.glassfish.hk2.api.Injectee; | |
import org.glassfish.hk2.api.InjectionResolver; | |
import org.glassfish.hk2.api.ServiceHandle; | |
import org.glassfish.hk2.api.TypeLiteral; | |
import org.glassfish.hk2.utilities.binding.AbstractBinder; | |
import org.glassfish.jersey.filter.LoggingFilter; | |
import org.glassfish.jersey.server.ResourceConfig; | |
import org.glassfish.jersey.test.JerseyTest; | |
import org.junit.Test; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertNotNull; | |
/** | |
* Run like any other JUnit test. Only one required dependency | |
* | |
* <dependency> | |
* <groupId>org.glassfish.jersey.test-framework.providers</groupId> | |
* <artifactId>jersey-test-framework-provider-inmemory</artifactId> | |
* <version>2.22.1</version> | |
* </dependency> | |
* | |
* @author Paul Samsotha | |
*/ | |
public class NestedInjectionTest extends JerseyTest { | |
@Target(ElementType.FIELD) | |
@Retention(RetentionPolicy.RUNTIME) | |
public static @interface CustomInject {} | |
public static class ChildObject { | |
String getName() { | |
return getClass().getSimpleName(); | |
} | |
} | |
public static class ParentObject { | |
@CustomInject | |
private ChildObject object; | |
String getResult() { | |
assertNotNull(object); | |
return this.getClass().getSimpleName() + ":" + object.getName(); | |
} | |
} | |
public static class CustomInjectResolver implements InjectionResolver<CustomInject> { | |
@Inject | |
@Named(InjectionResolver.SYSTEM_RESOLVER_NAME) | |
InjectionResolver<Inject> systemInjectionResolver; | |
@Override | |
public Object resolve(Injectee injectee, ServiceHandle<?> root) { | |
Type requiredType = injectee.getRequiredType(); | |
return (ChildObject.class.equals(requiredType) | |
|| ParentObject.class.equals(requiredType)) | |
? systemInjectionResolver.resolve(injectee, root) | |
: null; | |
} | |
@Override | |
public boolean isConstructorParameterIndicator() { return false; } | |
@Override | |
public boolean isMethodParameterIndicator() { return false; } | |
} | |
private static class Binder extends AbstractBinder { | |
@Override | |
protected void configure() { | |
bindAsContract(ParentObject.class); | |
bindAsContract(ChildObject.class); | |
bind(CustomInjectResolver.class) | |
.to(new TypeLiteral<InjectionResolver<CustomInject>>(){}) | |
.in(Singleton.class); | |
} | |
} | |
@Path("test") | |
public static class TestResource { | |
@CustomInject | |
ParentObject object; | |
@GET | |
public String get() { | |
return object.getResult(); | |
} | |
} | |
@Override | |
public ResourceConfig configure() { | |
return new ResourceConfig(TestResource.class) | |
.register(new Binder()) | |
.register(new LoggingFilter(Logger.getAnonymousLogger(), true)); | |
} | |
@Test | |
public void should_inject_fine() { | |
final Response response = target("test").request().get(); | |
assertEquals(200, response.getStatus()); | |
assertEquals("ParentObject:ChildObject", response.readEntity(String.class)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment