MentaContainer

Compare Revisions

Ignore whitespace Rev 57 → Rev 56

/trunk/src/test/java/org/mentacontainer/impl/MentaContainerTest.java
4,7 → 4,6
 
import org.junit.Test;
import org.mentacontainer.Container;
import org.mentacontainer.Scope;
 
public class MentaContainerTest {
 
57,7 → 56,7
 
Container c = new MentaContainer();
 
c.ioc("myStr", String.class, Scope.SINGLETON).addInitValue("hello");
c.ioc("myStr", String.class, true).addInitValue("hello");
 
Assert.assertEquals("hello", c.get("myStr"));
 
69,63 → 68,6
 
Assert.assertTrue(s1.equals(s2));
}
private static class MyThread extends Thread {
private final Container c;
private final String key;
private String value = null;
public MyThread(Container c, String key) {
super();
this.c = c;
this.key = key;
}
@Override
public void run() {
for(int i = 0; i < 50; i++) {
String v = c.get(key);
if (this.value != null) {
Assert.assertTrue(this.value == v);
}
this.value = v;
}
}
public String getValue() { return value; }
}
@Test
public void testThreadLocal() throws Exception {
final Container c = new MentaContainer();
c.ioc("myStr", String.class, Scope.THREAD).addInitValue("saoj");
String s1 = c.get("myStr");
MyThread t1 = new MyThread(c, "myStr");
MyThread t2 = new MyThread(c, "myStr");
t1.start();
t2.start();
t1.join();
t2.join();
String s2 = t1.getValue();
String s3 = t2.getValue();
Assert.assertTrue(s1 != s2);
Assert.assertTrue(s2 != s3);
}
 
public static interface MyDAO {
199,7 → 141,7
c.ioc("myDAO", JdbcMyDAO.class);
c.ioc("aDependency", SomeDependency.class, Scope.SINGLETON).addProperty("name", "A super dependency!");
c.ioc("aDependency", SomeDependency.class, true /* singleton */).addProperty("name", "A super dependency!");
c.ioc("connection", Connection.class).addInitValue("A super JDBC connection!");
/trunk/src/main/java/org/mentacontainer/Scope.java
File deleted
\ No newline at end of file
/trunk/src/main/java/org/mentacontainer/impl/MentaContainer.java
10,7 → 10,6
import org.mentacontainer.ConfigurableComponent;
import org.mentacontainer.Container;
import org.mentacontainer.Dependency;
import org.mentacontainer.Scope;
import org.mentacontainer.util.InjectionUtils;
import org.mentacontainer.util.InjectionUtils.Provider;
 
23,28 → 22,11
 
private Map<String, Component> beans = new HashMap<String, Component>();
private Map<String, Scope> scopes = new HashMap<String, Scope>();
private Set<String> singletons = new HashSet<String>();
private Map<String, Object> singletonsCache = new HashMap<String, Object>();
private Map<String, ThreadLocal<Object>> threadLocalsCache = new HashMap<String, ThreadLocal<Object>>();
 
private Set<Dependency> dependencies = new HashSet<Dependency>();
public void clear(Scope scope) {
if (scope == Scope.SINGLETON) {
singletonsCache.clear();
} else if (scope == Scope.THREAD) {
for(ThreadLocal<Object> t : threadLocalsCache.values()) {
t.set(null);
}
}
}
 
public <T> T get(String key) {
 
52,19 → 34,19
 
Component c = beans.get(key);
Scope scope = scopes.get(key);
boolean isSingleton = singletons.contains(key);
 
Object target = null;
 
try {
 
if (scope == Scope.SINGLETON) {
if (isSingleton) {
 
if (singletonsCache.containsKey(key)) {
 
target = singletonsCache.get(key);
 
return (T) target; // no need to wire again...
return (T) target;
 
} else {
 
72,50 → 54,11
 
singletonsCache.put(key, target);
}
} else if (scope == Scope.THREAD) {
if (threadLocalsCache.containsKey(key)) {
ThreadLocal<Object> t = threadLocalsCache.get(key);
target = t.get();
if (target == null) { // different thread...
target = c.getInstance();
t.set(target);
// don't return... let it be wired...
} else {
return (T) target; // no need to wire again...
}
} else {
ThreadLocal<Object> t = new ThreadLocal<Object>();
target = c.getInstance();
t.set(target);
threadLocalsCache.put(key, t);
// let it be wired...
}
} else if (scope == Scope.NONE) {
 
} else {
 
target = c.getInstance();
 
} else {
throw new UnsupportedOperationException("Don't know how to handle scope: " + scope);
}
 
if (target != null) {
170,22 → 113,27
}
}
 
public Component ioc(String key, Component component, Scope scope) {
public Component ioc(String key, Component component, boolean isSingleton) {
beans.put(key, component);
singletonsCache.remove(key); // just in case we are overriding a previous singleton bean...
threadLocalsCache.remove(key); // just in case we are overriding a previous thread local...
if (isSingleton) {
singletons.add(key);
} else {
scopes.put(key, scope);
singletons.remove(key); // just in case...
}
 
return component;
}
public Component ioc(String key, Component component) {
return ioc(key, component, Scope.NONE);
return ioc(key, component, false);
}
public ConfigurableComponent ioc(String key, Class<? extends Object> klass) {
197,11 → 145,11
return cc;
}
public ConfigurableComponent ioc(String key, Class<? extends Object> klass, Scope scope) {
public ConfigurableComponent ioc(String key, Class<? extends Object> klass, boolean singleton) {
ConfigurableComponent cc = new MentaComponent(klass);
ioc(key, cc, scope);
ioc(key, cc, singleton);
return cc;
}
/trunk/src/main/java/org/mentacontainer/Container.java
7,7 → 7,7
* <li> Constructor injection for bean setup</li>
* <li> Setter injection for bean setup</li>
* <li> Auto-wiring based on name and type</li>
* <li> Scopes: Singleton and ThreadLocal</li>
* <li> Singleton</li>
* <li> Wiring of external beans with the beans configured in this container</li>
* <li> Annotation and XML free (programmatic configuration is the way to go!)
* </ul>
34,25 → 34,23
*
* @param key The key representing the bean to return. The name of the bean in the container.
* @param klass The class used to instantiate the bean, in other words, its implementation.
* @param scope The scope of the component.
* @param singleton A boolean to indicate if this bean will be a singleton.
* @return The component created as a ConfigurableComponent. (Fluent API)
* @see Scope
*/
public ConfigurableComponent ioc(String key, Class<? extends Object> klass, Scope scope);
public ConfigurableComponent ioc(String key, Class<? extends Object> klass, boolean singleton);
/**
* Same as {@link #ioc(String, Class, Scope)} except that it assumes
* there is no scope (Scope.NONE).
* Same as {@link #ioc(String, Class, boolean)} except that it assumes
* singleton is false.
*
* @param key
* @param klass
* @return The component created as a ConfigurableComponent. (Fluent API)
* @see Scope
*/
public ConfigurableComponent ioc(String key, Class<?extends Object> klass);
/**
* Set up IoC based on the component passed. The scope assumed is NONE.
* Set up IoC based on the component passed.
*
* @param key The key representing the bean to return. The name of the bean in the container.
* @param component The component for the IoC.
62,16 → 60,15
public Component ioc(String key, Component component);
/**
* Set up IoC based on the component passed. Specify the scope of the component.
* Set up IoC based on the component passed. Specify whether this will be a singleton component.
*
* @param key The key representing the bean to return. The name of the bean in the container.
* @param component The component for the IoC.
* @param scope The scope used by the component.
* @param isSingleton Should this component be treated as a singleton?
* @return The component passed as a parameter.
* @see Component
* @see Scope
*/
public Component ioc(String key, Component component, Scope scope);
public Component ioc(String key, Component component, boolean isSingleton);
/**
* Configure a bean dependency to be auto-wired by the container. In general you want the
126,12 → 123,4
* @return true if the container contains this bean.
*/
public boolean contains(String key);
/**
* Clear all cached instances for that scope. If you have a thread pool for example you will
* have to clear the THREAD scope when your thread is returned to the pool.
*
* @param scope The scope to be cleared.
*/
public void clear(Scope scope);
}
/trunk/src/main/java/org/mentacontainer/example/BasicOperations.java
3,7 → 3,6
import java.util.Date;
 
import org.mentacontainer.Container;
import org.mentacontainer.Scope;
import org.mentacontainer.impl.MentaContainer;
 
public class BasicOperations {
45,7 → 44,7
Container c = new MentaContainer();
c.ioc("myString", String.class, Scope.SINGLETON).addInitValue("saoj");
c.ioc("myString", String.class, true /* singleton */).addInitValue("saoj");
String s1 = c.get("myString");