From f94e86df1dade449189d4110c10a2ea68b3cde01 Mon Sep 17 00:00:00 2001 From: Josha von Gizycki Date: Tue, 14 Feb 2017 17:19:16 +0100 Subject: [PATCH] add logic to singleton test refactor internal workings in sdicontainer --- .../de/joshavg/simpledic/IntegrityCheck.java | 10 +++- .../de/joshavg/simpledic/SdiContainer.java | 46 ++++++++-------- .../simpledic/SdiContainerInterface.java | 1 + .../joshavg/simpledic/ServiceDefinition.java | 54 ++++++++++++++++--- .../de/joshavg/simpledic/SingletonTest.java | 13 +++++ .../services/DependsOnNoDependencies.java | 8 +++ src/test/resources/singleton.properties | 2 + 7 files changed, 103 insertions(+), 31 deletions(-) diff --git a/src/main/java/de/joshavg/simpledic/IntegrityCheck.java b/src/main/java/de/joshavg/simpledic/IntegrityCheck.java index 3359946..d27aab9 100644 --- a/src/main/java/de/joshavg/simpledic/IntegrityCheck.java +++ b/src/main/java/de/joshavg/simpledic/IntegrityCheck.java @@ -56,7 +56,10 @@ class IntegrityCheck { LOG.info("found service class for name {}: {}", key, value); try { Class clz = Class.forName(value); - definitions.add(new ServiceDefinition().setClz(clz).setName(value)); + definitions.add(new ServiceDefinition() + .setClz(clz) + .setName(key) + .setSingleton(isSingleton(key))); return clz; } catch (ClassNotFoundException e) { throw new SdicClassNotFound(e); @@ -64,6 +67,11 @@ class IntegrityCheck { }).collect(Collectors.toList()); } + private boolean isSingleton(String name) { + return props.containsKey(name + ".singleton") && "true" + .equals(props.get(name + ".singleton")); + } + private void checkConstructorDependencies(List> services) { services.stream() // get the first and only constructor diff --git a/src/main/java/de/joshavg/simpledic/SdiContainer.java b/src/main/java/de/joshavg/simpledic/SdiContainer.java index 26eab58..7b68a2d 100644 --- a/src/main/java/de/joshavg/simpledic/SdiContainer.java +++ b/src/main/java/de/joshavg/simpledic/SdiContainer.java @@ -9,9 +9,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Properties; -import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,20 +17,20 @@ public class SdiContainer implements SdiContainerInterface { private static final Logger LOG = LoggerFactory.getLogger(SdiContainer.class); - private final Properties props; private final List definitions; - private final Map, Object> singletons; + private final Map singletons; - private SdiContainer(Properties props, List definitions) { - this.props = props; + private SdiContainer(List definitions) { this.definitions = definitions; this.singletons = new HashMap<>(); } + @SuppressWarnings("unused") public static SdiContainer load() { return load("sdic.properties"); } + @SuppressWarnings("WeakerAccess") public static SdiContainer load(String filename) { Properties props = new Properties(); @@ -49,47 +47,47 @@ public class SdiContainer implements SdiContainerInterface { IntegrityCheck integrityCheck = new IntegrityCheck(props); integrityCheck.check(); - return new SdiContainer(props, integrityCheck.getDefinitions()); + return new SdiContainer(integrityCheck.getDefinitions()); } - private List> serviceClasses() { - return definitions.stream().map(ServiceDefinition::getClz).collect(Collectors.toList()); + private ServiceDefinition getDefinition(Class clz) { + return definitions.stream() + .filter(d -> d.getClz() == clz) + .findFirst() + .orElse(null); } @Override public T getInstance(Class clz) { LOG.trace("instance ordered: ", clz); - if (!serviceClasses().contains(clz)) { + ServiceDefinition definition = getDefinition(clz); + if (definition == null) { throw new ClassNotRegistered(clz); } - if (isStoredAsSingleton(clz)) { - return clz.cast(singletons.get(clz)); + LOG.debug("service name is {}", definition.getName()); + + if (isStoredAsSingleton(definition)) { + return clz.cast(singletons.get(definition)); } try { T instance = new Instantiator<>(clz, this).createInstance(); - handleSingleton(clz, instance); + handleSingleton(definition, instance); return instance; } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) { throw new SdicInstantiationException(e); } } - private void handleSingleton(Class clz, T instance) { - String key = props.entrySet().stream() - .filter(e -> Objects.equals(clz.getName(), String.valueOf(e.getValue()))) - .map(e -> e.getKey().toString()) - .findFirst() - .orElse(""); - - if (props.containsKey(key + ".singleton") && "true".equals(props.get(key + ".singleton"))) { - singletons.put(clz, instance); + private void handleSingleton(ServiceDefinition definition, T instance) { + if (definition.isSingleton()) { + singletons.put(definition, instance); } } - private boolean isStoredAsSingleton(Class clz) { - return singletons.containsKey(clz); + private boolean isStoredAsSingleton(ServiceDefinition def) { + return singletons.containsKey(def); } } diff --git a/src/main/java/de/joshavg/simpledic/SdiContainerInterface.java b/src/main/java/de/joshavg/simpledic/SdiContainerInterface.java index 70cb0bc..637eaff 100644 --- a/src/main/java/de/joshavg/simpledic/SdiContainerInterface.java +++ b/src/main/java/de/joshavg/simpledic/SdiContainerInterface.java @@ -1,5 +1,6 @@ package de.joshavg.simpledic; +@SuppressWarnings("WeakerAccess") public interface SdiContainerInterface { T getInstance(Class clz); diff --git a/src/main/java/de/joshavg/simpledic/ServiceDefinition.java b/src/main/java/de/joshavg/simpledic/ServiceDefinition.java index 1107e44..69d89fc 100644 --- a/src/main/java/de/joshavg/simpledic/ServiceDefinition.java +++ b/src/main/java/de/joshavg/simpledic/ServiceDefinition.java @@ -7,31 +7,73 @@ class ServiceDefinition { private Class clz; private String name; private Constructor constructor; + private boolean isSingleton; - public Class getClz() { + Class getClz() { return clz; } - public ServiceDefinition setClz(Class clz) { + ServiceDefinition setClz(Class clz) { this.clz = clz; return this; } - public String getName() { + String getName() { return name; } - public ServiceDefinition setName(String name) { + ServiceDefinition setName(String name) { this.name = name; return this; } - public Constructor getConstructor() { + Constructor getConstructor() { return constructor; } - public ServiceDefinition setConstructor(Constructor constructor) { + ServiceDefinition setConstructor(Constructor constructor) { this.constructor = constructor; return this; } + + boolean isSingleton() { + return isSingleton; + } + + ServiceDefinition setSingleton(boolean singleton) { + isSingleton = singleton; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ServiceDefinition that = (ServiceDefinition) o; + + if (isSingleton != that.isSingleton) { + return false; + } + if (!clz.equals(that.clz)) { + return false; + } + if (!name.equals(that.name)) { + return false; + } + return constructor.equals(that.constructor); + } + + @Override + public int hashCode() { + int result = clz.hashCode(); + result = 31 * result + name.hashCode(); + result = 31 * result + constructor.hashCode(); + result = 31 * result + (isSingleton ? 1 : 0); + return result; + } } diff --git a/src/test/java/de/joshavg/simpledic/SingletonTest.java b/src/test/java/de/joshavg/simpledic/SingletonTest.java index e743451..29d0a8b 100644 --- a/src/test/java/de/joshavg/simpledic/SingletonTest.java +++ b/src/test/java/de/joshavg/simpledic/SingletonTest.java @@ -1,8 +1,10 @@ package de.joshavg.simpledic; +import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.sameInstance; import static org.hamcrest.MatcherAssert.assertThat; +import de.joshavg.simpledic.services.DependsOnNoDependencies; import de.joshavg.simpledic.services.NoDependencies; import org.junit.Test; @@ -15,4 +17,15 @@ public class SingletonTest { sameInstance(container.getInstance(NoDependencies.class))); } + @Test + public void sameInstanceViaDependency() { + SdiContainer container = SdiContainer.load("singleton.properties"); + + DependsOnNoDependencies i1 = container.getInstance(DependsOnNoDependencies.class); + DependsOnNoDependencies i2 = container.getInstance(DependsOnNoDependencies.class); + + assertThat(i1, not(sameInstance(i2))); + assertThat(i1.getDependency(), sameInstance(i2.getDependency())); + } + } diff --git a/src/test/java/de/joshavg/simpledic/services/DependsOnNoDependencies.java b/src/test/java/de/joshavg/simpledic/services/DependsOnNoDependencies.java index c2e7ced..054ec6e 100644 --- a/src/test/java/de/joshavg/simpledic/services/DependsOnNoDependencies.java +++ b/src/test/java/de/joshavg/simpledic/services/DependsOnNoDependencies.java @@ -1,6 +1,14 @@ package de.joshavg.simpledic.services; public class DependsOnNoDependencies { + + private final NoDependencies b; + public DependsOnNoDependencies(NoDependencies b) { + this.b = b; + } + + public NoDependencies getDependency() { + return b; } } diff --git a/src/test/resources/singleton.properties b/src/test/resources/singleton.properties index 8a3b4b5..c6a1a91 100644 --- a/src/test/resources/singleton.properties +++ b/src/test/resources/singleton.properties @@ -1,2 +1,4 @@ service.one: de.joshavg.simpledic.services.NoDependencies service.one.singleton: true + +service.two: de.joshavg.simpledic.services.DependsOnNoDependencies