Skip to content

Commit

Permalink
Rename get(Class) to getSingleton(Class), add Nullable to interface w…
Browse files Browse the repository at this point in the history
…here applicable
  • Loading branch information
ljacqu committed Jun 20, 2016
1 parent acb13c4 commit 6989e85
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 42 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.0</version>
</dependency>

<!-- Testing -->
<dependency>
Expand Down
17 changes: 16 additions & 1 deletion src/main/java/ch/jalu/injector/Injector.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package ch.jalu.injector;

import javax.annotation.Nullable;
import java.lang.annotation.Annotation;

/**
* The injector interface.
*/
public interface Injector {

/**
Expand All @@ -28,7 +32,7 @@ public interface Injector {
* @param <T> the class' type
* @return object of the class' type
*/
<T> T get(Class<T> clazz);
<T> T getSingleton(Class<T> clazz);

/**
* Request-scoped method to instantiate a new object of the given class. The injector does <i>not</i> keep track
Expand All @@ -40,4 +44,15 @@ public interface Injector {
*/
<T> T newInstance(Class<T> clazz);

/**
* Returns an instance of the given class if available. This simply returns the instance if present and
* otherwise {@code null}. Calling this method will not instantiate anything.
*
* @param clazz the class to retrieve the instance for
* @param <T> the class' type
* @return instance or null if none available
*/
@Nullable
<T> T getIfAvailable(Class<T> clazz);

}
26 changes: 6 additions & 20 deletions src/main/java/ch/jalu/injector/InjectorImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import ch.jalu.injector.exceptions.InjectorException;
import ch.jalu.injector.instantiation.Instantiation;
import ch.jalu.injector.utils.InjectorUtils;
import ch.jalu.injector.utils.ReflectionUtils;

import javax.annotation.PostConstruct;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
Expand All @@ -15,7 +15,7 @@
import java.util.Set;

/**
* Dependency injector of AuthMe: initializes and injects services and tasks.
* Dependency injector implementation: initializes and injects classes.
* <p>
* Only constructor and field injection are supported, indicated with the JSR330
* {@link javax.inject.Inject @Inject} annotation.
Expand All @@ -41,7 +41,7 @@ public InjectorImpl(String... allowedPackages) {
}

@Override
public <T> T get(Class<T> clazz) {
public <T> T getSingleton(Class<T> clazz) {
return get(clazz, new HashSet<Class<?>>());
}

Expand Down Expand Up @@ -69,14 +69,7 @@ public <T> T newInstance(Class<T> clazz) {
return instantiate(clazz, new HashSet<Class<?>>());
}

/**
* Returns an instance of the given class if available. This simply returns the instance if present and
* otherwise {@code null}. Calling this method will not instantiate anything.
*
* @param clazz the class to retrieve the instance for
* @param <T> the class' type
* @return instance or null if none available
*/
@Override
public <T> T getIfAvailable(Class<T> clazz) {
if (Annotation.class.isAssignableFrom(clazz)) {
throw new InjectorException("Annotations may not be retrieved in this way!");
Expand All @@ -87,7 +80,7 @@ public <T> T getIfAvailable(Class<T> clazz) {
/**
* Returns an instance of the given class by retrieving it or by instantiating it if not yet present.
*
* @param clazz the class to retrieve a value for
* @param clazz the class to retrieve the singleton instance for
* @param traversedClasses the list of traversed classes
* @param <T> the class' type
* @return instance or associated value (for annotations)
Expand Down Expand Up @@ -222,14 +215,7 @@ private void validatePackage(Class<?> clazz) {
*/
private static void executePostConstructMethod(Object object) {
Method postConstructMethod = InjectionHelper.getAndValidatePostConstructMethod(object.getClass());
if (postConstructMethod != null) {
try {
postConstructMethod.setAccessible(true);
postConstructMethod.invoke(object);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new InjectorException("Error executing @PostConstruct method", e);
}
}
ReflectionUtils.invokeMethod(postConstructMethod, object);
}

private static void validateInstantiable(Class<?> clazz) {
Expand Down
42 changes: 21 additions & 21 deletions src/test/java/ch/jalu/injector/InjectorImplTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public void setInitializer() {
@Test
public void shouldInitializeElements() {
// given / when
BetaManager betaManager = injector.get(BetaManager.class);
BetaManager betaManager = injector.getSingleton(BetaManager.class);

// then
assertThat(betaManager, not(nullValue()));
Expand All @@ -65,14 +65,14 @@ public void shouldInitializeElements() {
public void shouldThrowForInvalidPackage() {
// given / when / then
expectInjectorException("outside of the allowed packages");
injector.get(InvalidClass.class);
injector.getSingleton(InvalidClass.class);
}

@Test
public void shouldThrowForUnregisteredPrimitiveType() {
// given / when / then
expectInjectorException("Primitive types must be provided");
injector.get(int.class);
injector.getSingleton(int.class);
}

@Test
Expand All @@ -84,21 +84,21 @@ public void shouldPassValueByAnnotation() {
injector.provide(Duration.class, duration);

// when
ClassWithAnnotations object = injector.get(ClassWithAnnotations.class);
ClassWithAnnotations object = injector.getSingleton(ClassWithAnnotations.class);

// then
assertThat(object, not(nullValue()));
assertThat(object.getSize(), equalTo(size));
assertThat(object.getDuration(), equalTo(duration));
// some sample check to make sure we only have one instance of GammaService
assertThat(object.getGammaService(), equalTo(injector.get(BetaManager.class).getDependencies()[1]));
assertThat(object.getGammaService(), equalTo(injector.getSingleton(BetaManager.class).getDependencies()[1]));
}

@Test
public void shouldRecognizeCircularReferences() {
// given / when / then
expectInjectorException("Found cyclic dependency");
injector.get(CircularClasses.Circular3.class);
injector.getSingleton(CircularClasses.Circular3.class);
}

@Test
Expand All @@ -108,14 +108,14 @@ public void shouldThrowForUnregisteredAnnotation() {

// when / then
expectInjectorException("must be registered beforehand");
injector.get(ClassWithAnnotations.class);
injector.getSingleton(ClassWithAnnotations.class);
}

@Test
public void shouldThrowForFieldInjectionWithoutNoArgsConstructor() {
// given / when / then
expectInjectorException("Did not find injection method");
injector.get(BadFieldInjection.class);
injector.getSingleton(BadFieldInjection.class);
}

@Test
Expand All @@ -125,7 +125,7 @@ public void shouldInjectFieldsWithAnnotationsProperly() {
injector.provide(Duration.class, 13095L);

// when
FieldInjectionWithAnnotations result = injector.get(FieldInjectionWithAnnotations.class);
FieldInjectionWithAnnotations result = injector.getSingleton(FieldInjectionWithAnnotations.class);

// then
assertThat(result.getSize(), equalTo(2809375));
Expand All @@ -140,7 +140,7 @@ public void shouldInjectFieldsWithAnnotationsProperly() {
public void shouldThrowForAnnotationAsKey() {
// given / when / then
expectInjectorException("Cannot retrieve annotated elements in this way");
injector.get(Size.class);
injector.getSingleton(Size.class);
}

@Test
Expand Down Expand Up @@ -180,7 +180,7 @@ public void shouldExecutePostConstructMethod() {
injector.provide(Size.class, 15123);

// when
PostConstructTestClass testClass = injector.get(PostConstructTestClass.class);
PostConstructTestClass testClass = injector.getSingleton(PostConstructTestClass.class);

// then
assertThat(testClass.wasPostConstructCalled(), equalTo(true));
Expand All @@ -191,42 +191,42 @@ public void shouldExecutePostConstructMethod() {
public void shouldThrowForInvalidPostConstructMethod() {
// given / when / then
expectInjectorException("@PostConstruct method may not be static or have any parameters");
injector.get(InvalidPostConstruct.WithParams.class);
injector.getSingleton(InvalidPostConstruct.WithParams.class);
}

@Test
public void shouldThrowForStaticPostConstructMethod() {
// given / when / then
expectInjectorException("@PostConstruct method may not be static or have any parameters");
injector.get(InvalidPostConstruct.Static.class);
injector.getSingleton(InvalidPostConstruct.Static.class);
}

@Test
public void shouldForwardExceptionFromPostConstruct() {
// given / when / then
expectInjectorException("Error executing @PostConstruct method");
injector.get(InvalidPostConstruct.ThrowsException.class);
injector.getSingleton(InvalidPostConstruct.ThrowsException.class);
}

@Test
public void shouldThrowForMultiplePostConstructMethods() {
// given / when / then
expectInjectorException("Multiple methods with @PostConstruct");
injector.get(InvalidPostConstruct.MultiplePostConstructs.class);
injector.getSingleton(InvalidPostConstruct.MultiplePostConstructs.class);
}

@Test
public void shouldThrowForPostConstructNotReturningVoid() {
// given / when / then
expectInjectorException("@PostConstruct method must have return type void");
injector.get(InvalidPostConstruct.NotVoidReturnType.class);
injector.getSingleton(InvalidPostConstruct.NotVoidReturnType.class);
}

@Test
public void shouldThrowForAbstractNonRegisteredDependency() {
// given / when / then
expectInjectorException("cannot be instantiated");
injector.get(ClassWithAbstractDependency.class);
injector.getSingleton(ClassWithAbstractDependency.class);
}

@Test
Expand All @@ -236,7 +236,7 @@ public void shouldInstantiateWithImplementationOfAbstractDependency() {
injector.register(ClassWithAbstractDependency.AbstractDependency.class, concrete);

// when
ClassWithAbstractDependency cwad = injector.get(ClassWithAbstractDependency.class);
ClassWithAbstractDependency cwad = injector.getSingleton(ClassWithAbstractDependency.class);

// then
assertThat(cwad.getAbstractDependency() == concrete, equalTo(true));
Expand All @@ -256,7 +256,7 @@ public void shouldThrowForAlreadyRegisteredClass() {
@Test
public void shouldCreateNewUntrackedInstance() {
// given / when
AlphaService singletonScoped = injector.get(AlphaService.class);
AlphaService singletonScoped = injector.getSingleton(AlphaService.class);
AlphaService requestScoped = injector.newInstance(AlphaService.class);

// then
Expand All @@ -276,7 +276,7 @@ public void shouldThrowForStaticFieldInjection() {
public void shouldFallbackToSimpleInstantiationForPlainClass() {
// given / when
InstantiationFallbackClasses.HasFallbackDependency result =
injector.get(InstantiationFallbackClasses.HasFallbackDependency.class);
injector.getSingleton(InstantiationFallbackClasses.HasFallbackDependency.class);

// then
assertThat(result, not(nullValue()));
Expand All @@ -287,7 +287,7 @@ public void shouldFallbackToSimpleInstantiationForPlainClass() {
@Test
public void shouldRetrieveExistingInstancesOnly() {
// given
injector.get(GammaService.class);
injector.getSingleton(GammaService.class);

// when
AlphaService alphaService = injector.getIfAvailable(AlphaService.class);
Expand Down

0 comments on commit 6989e85

Please sign in to comment.