Rev 88 | Rev 93 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | soliveira | 1 | package org.mentacontainer; |
2 | |||
3 | /** |
||
4 | * A very simple container that provides: |
||
5 | * <ul> |
||
6 | * <li> Bean instantiation (duh!)</li> |
||
7 | * <li> Constructor injection for bean setup</li> |
||
8 | * <li> Setter injection for bean setup</li> |
||
81 | soliveira | 9 | * <li> Wiring based on name and type</li> |
57 | soliveira | 10 | * <li> Scopes: Singleton and ThreadLocal</li> |
20 | soliveira | 11 | * <li> Wiring of external beans with the beans configured in this container</li> |
25 | soliveira | 12 | * <li> Annotation and XML free (programmatic configuration is the way to go!) |
2 | soliveira | 13 | * </ul> |
14 | * |
||
15 | * It does not get much simpler than that. |
||
16 | * |
||
17 | * @author sergio.oliveira.jr@gmail.com |
||
18 | * |
||
19 | */ |
||
20 | public interface Container { |
||
21 | |||
22 | /** |
||
23 | * Get an instance from the container. |
||
24 | * |
||
25 | * The instance will be fully initialized (constructor and/or setters) and fully wired. |
||
26 | * |
||
27 | * @param key The key representing the bean to return. The name of the bean in the container. |
||
28 | * @return The fully initialized and wired bean. |
||
29 | */ |
||
41 | soliveira | 30 | public <T> T get(String key); |
2 | soliveira | 31 | |
91 | soliveira | 32 | public Class<? extends Object> getType(String key); |
33 | |||
2 | soliveira | 34 | /** |
35 | * Configure a bean to be returned with the given implementation when {@link #get(String)} is called. |
||
36 | * |
||
37 | * @param key The key representing the bean to return. The name of the bean in the container. |
||
38 | * @param klass The class used to instantiate the bean, in other words, its implementation. |
||
57 | soliveira | 39 | * @param scope The scope of the component. |
45 | soliveira | 40 | * @return The component created as a ConfigurableComponent. (Fluent API) |
57 | soliveira | 41 | * @see Scope |
2 | soliveira | 42 | */ |
88 | soliveira | 43 | public ConfigurableFactory ioc(String key, Class<? extends Object> klass, Scope scope); |
2 | soliveira | 44 | |
45 | /** |
||
57 | soliveira | 46 | * Same as {@link #ioc(String, Class, Scope)} except that it assumes |
47 | * there is no scope (Scope.NONE). |
||
2 | soliveira | 48 | * |
49 | * @param key |
||
50 | * @param klass |
||
45 | soliveira | 51 | * @return The component created as a ConfigurableComponent. (Fluent API) |
57 | soliveira | 52 | * @see Scope |
2 | soliveira | 53 | */ |
88 | soliveira | 54 | public ConfigurableFactory ioc(String key, Class<?extends Object> klass); |
2 | soliveira | 55 | |
56 | /** |
||
57 | soliveira | 57 | * Set up IoC based on the component passed. The scope assumed is NONE. |
2 | soliveira | 58 | * |
39 | soliveira | 59 | * @param key The key representing the bean to return. The name of the bean in the container. |
20 | soliveira | 60 | * @param component The component for the IoC. |
45 | soliveira | 61 | * @return The component passed as a parameter. |
88 | soliveira | 62 | * @see Factory |
20 | soliveira | 63 | */ |
88 | soliveira | 64 | public Factory ioc(String key, Factory component); |
20 | soliveira | 65 | |
66 | /** |
||
57 | soliveira | 67 | * Set up IoC based on the component passed. Specify the scope of the component. |
51 | soliveira | 68 | * |
69 | * @param key The key representing the bean to return. The name of the bean in the container. |
||
70 | * @param component The component for the IoC. |
||
57 | soliveira | 71 | * @param scope The scope used by the component. |
51 | soliveira | 72 | * @return The component passed as a parameter. |
88 | soliveira | 73 | * @see Factory |
57 | soliveira | 74 | * @see Scope |
51 | soliveira | 75 | */ |
88 | soliveira | 76 | public Factory ioc(String key, Factory component, Scope scope); |
51 | soliveira | 77 | |
78 | /** |
||
20 | soliveira | 79 | * Configure a bean dependency to be auto-wired by the container. In general you want the |
80 | * type of the dependency to be an interface, for loosely couple dependencies. It works like that:<br/><br/> |
||
81 | * |
||
2 | soliveira | 82 | * Whenever the container returns a bean, it checks to see if it has a property named <i>property</i> |
83 | * and if the type of the property is <i>klass</i>. If it does, then it looks for a bean named |
||
84 | * <i>source</i> and injects it inside the first bean it is returning. This approach is recursive |
||
85 | * so all properties are checked up the class hierarchy, until it reaches Object. |
||
86 | * |
||
87 | * @param property a bean property that will require another bean, in other words, the required |
||
88 | * bean will be injected in the property of the bean been requested from the container. (auto-wiring by name) |
||
20 | soliveira | 89 | * @param klass the type of the dependency, in other words, the type of the auto-wiring. (auto-wiring by type) |
2 | soliveira | 90 | * @param source The dependency itself, coming from the container as well, in other words, the bean that will be injected in the original bean |
91 | * @return The container itself. (Fluent API) |
||
92 | */ |
||
76 | soliveira | 93 | public Dependency wire(String property, Class<? extends Object> klass, String source); |
2 | soliveira | 94 | |
95 | /** |
||
76 | soliveira | 96 | * Same as {@link #wire(String, Class, String)} except that it assumes that the property name will be the source name, in other words, |
2 | soliveira | 97 | * the property name is the same as the bean name that will be injected as the dependency. |
98 | * |
||
99 | * @param property |
||
100 | * @param klass |
||
101 | * @return The container itself. (Fluent API) |
||
102 | */ |
||
76 | soliveira | 103 | public Dependency wire(String property, Class<? extends Object> klass); |
2 | soliveira | 104 | |
105 | /** |
||
21 | soliveira | 106 | * Setup a dependency. |
2 | soliveira | 107 | * |
21 | soliveira | 108 | * @param dependency The dependency to setup |
109 | * @return The dependency itself. (Fluent API) |
||
110 | * @see Dependency |
||
2 | soliveira | 111 | */ |
76 | soliveira | 112 | public Dependency wire(Dependency dependency); |
2 | soliveira | 113 | |
114 | /** |
||
115 | * Take a given bean and populate its properties with other beans coming from this container. Perhaps you can call this auto-wiring. |
||
116 | * You basically checking properties of the given bean and looking for values (by name and type!) inside the container. And injecting |
||
117 | * in the given bean, in other words, populating it. |
||
118 | * |
||
119 | * @param bean The bean to be populated with other beans from the container. |
||
120 | * @return The container itself. (Fluent API) |
||
121 | */ |
||
40 | soliveira | 122 | public Container populate(Object bean); |
4 | soliveira | 123 | |
124 | /** |
||
58 | soliveira | 125 | * Check whether the container currently has a value for this key. For example, |
126 | * if it is a singleton AND someone has requested it, the container will have it cached. |
||
127 | * The method is useful to check for an instance without forcing her creation. |
||
4 | soliveira | 128 | * |
129 | * @param key The key representing the bean inside the container. |
||
58 | soliveira | 130 | * @return true if the container has an instance cached in the scope for this key |
4 | soliveira | 131 | */ |
58 | soliveira | 132 | public boolean check(String key); |
57 | soliveira | 133 | |
134 | /** |
||
81 | soliveira | 135 | * Clear all cached instances for that scope. If you have a thread-pool for example you will |
136 | * want to clear the THREAD scope when your thread is returned to the pool. Because you have a thread |
||
137 | * pool you will have the SAME thread handling different requests and each request will need its own instances |
||
138 | * from the container. Therefore, each time you are done with a thread and it is returned to your thread-pool |
||
139 | * you can call clear to release the instances allocated and cached by the container. A web container and/or framework |
||
140 | * can use this feature to implement a REQUEST scope which is nothing more than the THREAD scope with clear. If the web |
||
141 | * container was not using a thread-pool, the THREAD scope would be equal to the REQUEST scope as each request would |
||
142 | * always be handled by a different thread. |
||
143 | * |
||
144 | * It does not make sense to clear a NONE scope (the method returns doing nothing). You can clear a SINGLETON scope if necessary. |
||
57 | soliveira | 145 | * |
146 | * @param scope The scope to be cleared. |
||
147 | */ |
||
148 | public void clear(Scope scope); |
||
58 | soliveira | 149 | |
150 | /** |
||
151 | * Clear a single key from cache and return the instance that was cached. |
||
152 | * |
||
153 | * @param key The key representing the bean inside the container. |
||
70 | soliveira | 154 | * @return The value that was cached and it is not anymore (was cleared) or null if nothing was cleared |
58 | soliveira | 155 | */ |
156 | public <T> T clear(String key); |
||
2 | soliveira | 157 | } |