#432 Injector improvements

- Separate FieldInjection from default fallback for no-Inject public no-args constructor classes
- Make CommandInitializer a normal, instantiable service
- Add various injections instead of fetching through command service
This commit is contained in:
ljacqu
2016-05-08 11:15:56 +02:00
parent 3e6223dc5a
commit 5e5836f167
50 changed files with 554 additions and 332 deletions
@@ -8,6 +8,7 @@ import fr.xephi.authme.initialization.samples.ClassWithAbstractDependency;
import fr.xephi.authme.initialization.samples.ClassWithAnnotations;
import fr.xephi.authme.initialization.samples.Duration;
import fr.xephi.authme.initialization.samples.FieldInjectionWithAnnotations;
import fr.xephi.authme.initialization.samples.InstantiationFallbackClasses;
import fr.xephi.authme.initialization.samples.InvalidClass;
import fr.xephi.authme.initialization.samples.InvalidPostConstruct;
import fr.xephi.authme.initialization.samples.InvalidStaticFieldInjection;
@@ -231,4 +232,16 @@ public class AuthMeServiceInitializerTest {
initializer.newInstance(InvalidStaticFieldInjection.class);
}
@Test
public void shouldFallbackToSimpleInstantiationForPlainClass() {
// given / when
InstantiationFallbackClasses.HasFallbackDependency result =
initializer.get(InstantiationFallbackClasses.HasFallbackDependency.class);
// then
assertThat(result, not(nullValue()));
assertThat(result.getGammaService(), not(nullValue()));
assertThat(result.getFallbackDependency(), not(nullValue()));
}
}
@@ -1,6 +1,7 @@
package fr.xephi.authme.initialization;
import fr.xephi.authme.initialization.samples.AlphaService;
import fr.xephi.authme.initialization.samples.BetaManager;
import fr.xephi.authme.initialization.samples.ClassWithAnnotations;
import fr.xephi.authme.initialization.samples.Duration;
import fr.xephi.authme.initialization.samples.GammaService;
@@ -20,7 +21,6 @@ import static org.junit.Assert.assertThat;
*/
public class ConstructorInjectionTest {
@SuppressWarnings("unchecked")
@Test
public void shouldReturnDependencies() {
// given
@@ -74,8 +74,7 @@ public class ConstructorInjectionTest {
@Test
public void shouldReturnNullForNoConstructorInjection() {
// given / when
@SuppressWarnings("rawtypes")
Injection<FieldInjection> injection = ConstructorInjection.provide(FieldInjection.class).get();
Injection<BetaManager> injection = ConstructorInjection.provide(BetaManager.class).get();
// then
assertThat(injection, nullValue());
@@ -105,6 +105,15 @@ public class FieldInjectionTest {
FieldInjection.provide(InvalidStaticFieldInjection.class).get();
}
@Test
public void shouldNotReturnFieldInjectionForZeroInjectFields() {
// given / when
Injection<NoInjectionClass> injection = FieldInjection.provide(NoInjectionClass.class).get();
// then
assertThat(injection, nullValue());
}
private static class ThrowingConstructor {
@SuppressWarnings("unused")
@Inject
@@ -115,4 +124,10 @@ public class FieldInjectionTest {
throw new UnsupportedOperationException("Exception in constructor");
}
}
private static class NoInjectionClass {
private BetaManager betaManager;
}
}
@@ -0,0 +1,68 @@
package fr.xephi.authme.initialization;
import fr.xephi.authme.initialization.samples.GammaService;
import fr.xephi.authme.initialization.samples.InstantiationFallbackClasses;
import org.junit.Test;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
/**
* Test for {@link InstantiationFallback}.
*/
public class InstantiationFallbackTest {
@Test
public void shouldInstantiateClass() {
// given
Injection<InstantiationFallbackClasses.FallbackClass> instantiation =
InstantiationFallback.provide(InstantiationFallbackClasses.FallbackClass.class).get();
// when
InstantiationFallbackClasses.FallbackClass result = instantiation.instantiateWith();
// then
assertThat(result, not(nullValue()));
}
@Test(expected = RuntimeException.class)
public void shouldThrowIfArgumentsAreSupplied() {
// given
Injection<InstantiationFallbackClasses.FallbackClass> instantiation =
InstantiationFallback.provide(InstantiationFallbackClasses.FallbackClass.class).get();
// when / then
instantiation.instantiateWith("some argument");
}
@Test
public void shouldReturnNullForClassWithInjectMethod() {
// given / when
Injection<InstantiationFallbackClasses.InvalidInjectOnMethodClass> instantiation =
InstantiationFallback.provide(InstantiationFallbackClasses.InvalidInjectOnMethodClass.class).get();
// then
assertThat(instantiation, nullValue());
}
@Test
public void shouldReturnNullForMissingNoArgsConstructor() {
// given / when
Injection<InstantiationFallbackClasses.InvalidFallbackClass> instantiation =
InstantiationFallback.provide(InstantiationFallbackClasses.InvalidFallbackClass.class).get();
// then
assertThat(instantiation, nullValue());
}
@Test
public void shouldReturnNullForDifferentInjectionType() {
// given / when
Injection<GammaService> instantiation = InstantiationFallback.provide(GammaService.class).get();
// then
assertThat(instantiation, nullValue());
}
}
@@ -0,0 +1,45 @@
package fr.xephi.authme.initialization.samples;
import javax.inject.Inject;
/**
* Sample class - triggers instantiation fallback.
*/
public abstract class InstantiationFallbackClasses {
public static final class FallbackClass {
// No @Inject annotations, public no-args constructor
}
public static final class HasFallbackDependency {
@Inject
private FallbackClass fallbackClass;
@Inject
private GammaService gammaService;
public GammaService getGammaService() {
return gammaService;
}
public FallbackClass getFallbackDependency() {
return fallbackClass;
}
}
public static final class InvalidFallbackClass {
private InvalidFallbackClass() {
// no-args constructor must be public for fallback instantiation
}
}
public static final class InvalidInjectOnMethodClass {
// We don't support method injection but this should still be detected and an exception returned
// Only use instantiation fallback if we're sure there isn't some sort of misconfiguration
@Inject
public void setGammaService(GammaService gammaService) {
// --
}
}
}