package com.netflix.governator.guice; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.util.concurrent.atomic.AtomicInteger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.junit.Assert; import org.junit.Test; import com.google.inject.AbstractModule; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.name.Names; import com.netflix.governator.annotations.Modules; import com.netflix.governator.guice.annotations.Bootstrap; public class TestBootstrap { private static final Logger LOG = LoggerFactory.getLogger(TestBootstrap.class); public static class TestAction implements PostInjectorAction { private boolean injected = false; private final String name; public TestAction(String name) { this.name = name; } @Override public void call(Injector injector) { LOG.info("TestAction: " + name); injected = true; } String getName() { return name; } boolean isInjected() { return injected; } } @Documented @Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Bootstrap(SuiteBootstrap.class) public static @interface Suite1 { String name(); } @Documented @Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Bootstrap(bootstrap=ApplicationBootstrap.class) public static @interface Application { String name(); } @Documented @Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Bootstrap(bootstrap=Application2Bootstrap.class) public static @interface Application2 { String name(); } @Documented @Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Bootstrap(module=Module1Bootstrap.class) public static @interface Module1 { String name(); } public static class SuiteBootstrap implements LifecycleInjectorBuilderSuite { private final Suite1 suite1; @Inject SuiteBootstrap(Suite1 suite1) { this.suite1 = suite1; } @Override public void configure(LifecycleInjectorBuilder builder) { builder.withAdditionalModules(new AbstractModule() { @Override protected void configure() { bind(String.class).annotatedWith(Names.named("suite1")).toInstance(suite1.name()); } }); } } public static class ApplicationBootstrap implements BootstrapModule { private Application application; @Inject public ApplicationBootstrap(Application application) { this.application = application; } @Override public void configure(BootstrapBinder binder) { binder.bindPostInjectorAction().toInstance(new TestAction(getClass().getSimpleName())); binder.include(new AbstractModule() { @Override protected void configure() { bind(String.class).annotatedWith(Names.named("application")).toInstance(application.name()); } }); } } public static class Application2Bootstrap implements BootstrapModule { @Override public void configure(BootstrapBinder binder) { binder.bindPostInjectorAction().toInstance(new TestAction(getClass().getSimpleName())); } } public static class Module1Bootstrap extends AbstractModule { private Module1 module1; @Inject Module1Bootstrap(Module1 module1) { this.module1 = module1; } @Override public void configure() { bind(String.class).annotatedWith(Names.named("module1")).toInstance(module1.name()); } } public static class InitModule extends AbstractModule { @Inject InitModule(Application application) { Assert.assertEquals("foo", application.name()); } @Override protected void configure() { bind(AtomicInteger.class).annotatedWith(Names.named("init")).toInstance(new AtomicInteger()); } } @Application(name="foo") @Application2(name="goo") @Suite1(name="suite1") @Module1(name="module1") @Modules(include={InitModule.class}) public static class MyApplication extends AbstractModule { @Override protected void configure() { bind(String.class).annotatedWith(Names.named("bar")).toInstance("test"); } } @Test public void testAnnotationWiringAndInjection() { Injector injector = LifecycleInjector.bootstrap(MyApplication.class); Assert.assertEquals("foo", injector.getInstance(Key.get(String.class, Names.named("application")))); Assert.assertEquals("module1", injector.getInstance(Key.get(String.class, Names.named("module1")))); Assert.assertEquals("suite1", injector.getInstance(Key.get(String.class, Names.named("suite1")))); Assert.assertEquals("test", injector.getInstance(Key.get(String.class, Names.named("bar")))); } }