Rev 88 |
Rev 93 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
package org.mentacontainer;
/**
* A very simple container that provides:
* <ul>
* <li> Bean instantiation (duh!)</li>
* <li> Constructor injection for bean setup</li>
* <li> Setter injection for bean setup</li>
* <li> Wiring based on name and type</li>
* <li> Scopes: Singleton and ThreadLocal</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>
*
* It does not get much simpler than that.
*
* @author sergio.oliveira.jr@gmail.com
*
*/
public interface Container {
/**
* Get an instance from the container.
*
* The instance will be fully initialized (constructor and/or setters) and fully wired.
*
* @param key The key representing the bean to return. The name of the bean in the container.
* @return The fully initialized and wired bean.
*/
public <T
> T get
(String key
);
public Class<? extends Object> getType
(String key
);
/**
* Configure a bean to be returned with the given implementation when {@link #get(String)} is called.
*
* @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.
* @return The component created as a ConfigurableComponent. (Fluent API)
* @see Scope
*/
public ConfigurableFactory ioc
(String key,
Class<? extends Object> klass, Scope scope
);
/**
* Same as {@link #ioc(String, Class, Scope)} except that it assumes
* there is no scope (Scope.NONE).
*
* @param key
* @param klass
* @return The component created as a ConfigurableComponent. (Fluent API)
* @see Scope
*/
public ConfigurableFactory ioc
(String key,
Class<?extends Object> klass
);
/**
* Set up IoC based on the component passed. The scope assumed is NONE.
*
* @param key The key representing the bean to return. The name of the bean in the container.
* @param component The component for the IoC.
* @return The component passed as a parameter.
* @see Factory
*/
public Factory ioc
(String key, Factory component
);
/**
* Set up IoC based on the component passed. Specify the scope of the 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.
* @return The component passed as a parameter.
* @see Factory
* @see Scope
*/
public Factory ioc
(String key, Factory component, Scope scope
);
/**
* Configure a bean dependency to be auto-wired by the container. In general you want the
* type of the dependency to be an interface, for loosely couple dependencies. It works like that:<br/><br/>
*
* Whenever the container returns a bean, it checks to see if it has a property named <i>property</i>
* and if the type of the property is <i>klass</i>. If it does, then it looks for a bean named
* <i>source</i> and injects it inside the first bean it is returning. This approach is recursive
* so all properties are checked up the class hierarchy, until it reaches Object.
*
* @param property a bean property that will require another bean, in other words, the required
* bean will be injected in the property of the bean been requested from the container. (auto-wiring by name)
* @param klass the type of the dependency, in other words, the type of the auto-wiring. (auto-wiring by type)
* @param source The dependency itself, coming from the container as well, in other words, the bean that will be injected in the original bean
* @return The container itself. (Fluent API)
*/
public Dependency wire
(String property,
Class<? extends Object> klass,
String source
);
/**
* Same as {@link #wire(String, Class, String)} except that it assumes that the property name will be the source name, in other words,
* the property name is the same as the bean name that will be injected as the dependency.
*
* @param property
* @param klass
* @return The container itself. (Fluent API)
*/
public Dependency wire
(String property,
Class<? extends Object> klass
);
/**
* Setup a dependency.
*
* @param dependency The dependency to setup
* @return The dependency itself. (Fluent API)
* @see Dependency
*/
public Dependency wire
(Dependency dependency
);
/**
* Take a given bean and populate its properties with other beans coming from this container. Perhaps you can call this auto-wiring.
* You basically checking properties of the given bean and looking for values (by name and type!) inside the container. And injecting
* in the given bean, in other words, populating it.
*
* @param bean The bean to be populated with other beans from the container.
* @return The container itself. (Fluent API)
*/
public Container populate
(Object bean
);
/**
* Check whether the container currently has a value for this key. For example,
* if it is a singleton AND someone has requested it, the container will have it cached.
* The method is useful to check for an instance without forcing her creation.
*
* @param key The key representing the bean inside the container.
* @return true if the container has an instance cached in the scope for this key
*/
public boolean check
(String key
);
/**
* Clear all cached instances for that scope. If you have a thread-pool for example you will
* want to clear the THREAD scope when your thread is returned to the pool. Because you have a thread
* pool you will have the SAME thread handling different requests and each request will need its own instances
* from the container. Therefore, each time you are done with a thread and it is returned to your thread-pool
* you can call clear to release the instances allocated and cached by the container. A web container and/or framework
* can use this feature to implement a REQUEST scope which is nothing more than the THREAD scope with clear. If the web
* container was not using a thread-pool, the THREAD scope would be equal to the REQUEST scope as each request would
* always be handled by a different thread.
*
* It does not make sense to clear a NONE scope (the method returns doing nothing). You can clear a SINGLETON scope if necessary.
*
* @param scope The scope to be cleared.
*/
public void clear
(Scope scope
);
/**
* Clear a single key from cache and return the instance that was cached.
*
* @param key The key representing the bean inside the container.
* @return The value that was cached and it is not anymore (was cleared) or null if nothing was cleared
*/
public <T
> T clear
(String key
);
}