Skip to content

Commit 7793cb5

Browse files
committed
add #injector method that offers a customized creation of the injector
1 parent f7bc1da commit 7793cb5

File tree

3 files changed

+106
-7
lines changed

3 files changed

+106
-7
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package org.jooby.issues;
2+
3+
import com.google.inject.Guice;
4+
import com.google.inject.Injector;
5+
import org.jooby.test.ServerFeature;
6+
import org.junit.*;
7+
8+
import java.util.concurrent.atomic.AtomicReference;
9+
10+
/**
11+
* @author Johannes Schneider (<a href="mailto:[email protected]">[email protected]</a>)
12+
*/
13+
public class PullRequest583Test extends ServerFeature {
14+
private final AtomicReference<Injector> createdInjector = new AtomicReference<>();
15+
16+
{
17+
injector((stage, module) -> {
18+
Injector injector = Guice.createInjector(module);
19+
createdInjector.set(injector);
20+
return injector;
21+
});
22+
}
23+
24+
@Test
25+
public void appShouldBeMountedOnApplicationPath() throws Exception {
26+
Assert.assertNull(createdInjector.get());
27+
28+
start();
29+
try {
30+
Injector injector = require(Injector.class);
31+
Assert.assertNotNull(injector);
32+
Assert.assertSame(injector, createdInjector.get());
33+
} finally {
34+
stop();
35+
}
36+
}
37+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package org.jooby.issues;
2+
3+
import com.google.inject.Guice;
4+
import com.google.inject.Injector;
5+
import org.jooby.test.ServerFeature;
6+
import org.junit.*;
7+
8+
import java.util.concurrent.atomic.AtomicReference;
9+
10+
/**
11+
* @author Johannes Schneider (<a href="mailto:[email protected]">[email protected]</a>)
12+
*/
13+
public class PullRequest583WithChildInjectorTest extends ServerFeature {
14+
private final AtomicReference<Injector> createdInjector = new AtomicReference<>();
15+
16+
private final Injector parentInjector = Guice.createInjector(
17+
binder -> binder.bind(MyInjectedClass.class).toInstance(new MyInjectedClass()));
18+
19+
{
20+
21+
injector((stage, module) -> {
22+
Injector injector = parentInjector.createChildInjector(module);
23+
createdInjector.set(injector);
24+
return injector;
25+
});
26+
}
27+
28+
@Test
29+
public void appShouldBeMountedOnApplicationPath() throws Exception {
30+
Assert.assertNull(createdInjector.get());
31+
32+
start();
33+
try {
34+
Injector injector = require(Injector.class);
35+
Assert.assertSame(parentInjector.getInstance(MyInjectedClass.class), injector.getInstance(MyInjectedClass.class));
36+
} finally {
37+
stop();
38+
}
39+
}
40+
41+
private static class MyInjectedClass {
42+
}
43+
44+
}

jooby/src/main/java/org/jooby/Jooby.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
import java.util.concurrent.TimeUnit;
8383
import java.util.concurrent.atomic.AtomicBoolean;
8484
import java.util.concurrent.atomic.AtomicReference;
85+
import java.util.function.BiFunction;
8586
import java.util.function.Consumer;
8687
import java.util.function.Function;
8788
import java.util.function.Predicate;
@@ -696,6 +697,11 @@ public EnvDep(final Predicate<String> predicate, final Consumer<Config> callback
696697

697698
private boolean throwBootstrapException;
698699

700+
/**
701+
* creates the injector
702+
*/
703+
private transient BiFunction<Stage, com.google.inject.Module, Injector> injectorFactory = Guice::createInjector;
704+
699705
/**
700706
* Creates a new {@link Jooby} application.
701707
*/
@@ -2016,6 +2022,17 @@ public Jooby map(final Mapper<?> mapper) {
20162022
return this;
20172023
}
20182024

2025+
/**
2026+
* Use the injection provider to create the Guice injector
2027+
*
2028+
* @param injectorFactory the injection provider
2029+
* @return this instance.
2030+
*/
2031+
public Jooby injector(final BiFunction<Stage, com.google.inject.Module, Injector> injectorFactory) {
2032+
this.injectorFactory = injectorFactory;
2033+
return this;
2034+
}
2035+
20192036
/**
20202037
* Bind the provided abstract type to the given implementation:
20212038
*
@@ -2556,8 +2573,7 @@ private Injector bootstrap(final Config args,
25562573
xss(finalEnv);
25572574

25582575
/** dependency injection */
2559-
@SuppressWarnings("unchecked")
2560-
Injector injector = Guice.createInjector(stage, binder -> {
2576+
com.google.inject.Module joobyModule = binder -> {
25612577

25622578
/** type converters */
25632579
new TypeConverters().configure(binder);
@@ -2592,8 +2608,8 @@ private Injector bootstrap(final Config args,
25922608
binder.bind(SSLContext.class).toProvider(SslContextProvider.class);
25932609

25942610
/** routes */
2595-
Multibinder<Route.Definition> definitions = Multibinder
2596-
.newSetBinder(binder, Route.Definition.class);
2611+
Multibinder<Definition> definitions = Multibinder
2612+
.newSetBinder(binder, Definition.class);
25972613

25982614
/** web sockets */
25992615
Multibinder<WebSocket.Definition> sockets = Multibinder
@@ -2689,10 +2705,10 @@ private Injector bootstrap(final Config args,
26892705
} else {
26902706
binder.bind(SessionManager.class).to(ServerSessionManager.class).asEagerSingleton();
26912707
if (sstore instanceof Class) {
2692-
binder.bind(Session.Store.class).to((Class<? extends Store>) sstore)
2708+
binder.bind(Store.class).to((Class<? extends Store>) sstore)
26932709
.asEagerSingleton();
26942710
} else {
2695-
binder.bind(Session.Store.class).toInstance((Store) sstore);
2711+
binder.bind(Store.class).toInstance((Store) sstore);
26962712
}
26972713
}
26982714

@@ -2712,7 +2728,9 @@ private Injector bootstrap(final Config args,
27122728

27132729
/** executors. */
27142730
executors.forEach(it -> it.accept(binder));
2715-
});
2731+
};
2732+
@SuppressWarnings("unchecked")
2733+
Injector injector = injectorFactory.apply(stage, joobyModule);
27162734

27172735
onStart.addAll(0, finalEnv.startTasks());
27182736
onStarted.addAll(0, finalEnv.startedTasks());

0 commit comments

Comments
 (0)