001 /*
002 * ============================================================================
003 * GNU Lesser General Public License
004 * ============================================================================
005 *
006 * Beanlet - JSE Application Container.
007 * Copyright (C) 2006 Leon van Zantvoort
008 *
009 * This library is free software; you can redistribute it and/or
010 * modify it under the terms of the GNU Lesser General Public
011 * License as published by the Free Software Foundation; either
012 * version 2.1 of the License, or (at your option) any later version.
013 *
014 * This library is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 * Lesser General Public License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this library; if not, write to the Free Software
021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022 *
023 * Leon van Zantvoort
024 * 243 Acalanes Drive #11
025 * Sunnyvale, CA 94086
026 * USA
027 *
028 * zantvoort@users.sourceforge.net
029 * http://beanlet.org
030 */
031 package org.beanlet;
032
033 import java.lang.annotation.ElementType;
034 import java.lang.annotation.Retention;
035 import java.lang.annotation.RetentionPolicy;
036 import java.lang.annotation.Target;
037
038
039 /**
040 * <p>Members marked with this annotation are injected by the application
041 * container during beanlet instance creation.</p>
042 *
043 * <p>Dependency injection is supported for all member types - constructors,
044 * methods, and fields. Constructor dependency injection is used for
045 * injecting one or more objects into the constructor of a beanlet, resulting in
046 * a new beanlet instance. Alternatively, beanlet instances can be created by a
047 * (static) factory method. This factory method may defined by any class.
048 * Only one constructor or factory method may be marked with this annotation to
049 * avoid ambiguoutiy.
050 * </p>
051 *
052 * <p>Setter dependency injection is applied to all fields and (non-static)
053 * methods that are marked with this annotation.</p>
054 *
055 * <p>Dependency injection is performed before any lifecycle methods are invoked
056 * on the beanlet instance. All members that are marked for (non-optional)
057 * dependency injection are guaranteed to be injected, otherwise beanlet
058 * instance creation fails.</p>
059 *
060 * <p><h3>Injectant Resolution</h3>
061 * <p>
062 * This section explains the process of finding the object to be injected -
063 * further referred to as injectant - for a member that is target to dependency
064 * injection. The following steps are performed by the application container
065 * in listed order.
066 * </p>
067 * <p>
068 * <b>(1)</b> First step is explicit dependency injection. The {@code Inject}
069 * annotation specifies a value to be injected through the
070 * {@link #value}, {@link #collection} or {@link #map} methods.
071 * </p>
072 * <p>
073 * <b>(2)</b> The container performs step two of injectant resulution if and
074 * only if step one does not result in an injectant. During step two the
075 * container checks if the member to be injected expresses a framework class.
076 * These classes include: {@link BeanletApplicationContext},
077 * {@link BeanletContext}, {@link BeanletMetaData}, {@link BeanletFactory} and
078 * {@link BeanletReference}. If the target matches
079 * {@code BeanletApplicationContext} the instance returned
080 * by {@code BeanletApplicationContext.instance()} is injected. If the target
081 * matches {@code BeanletContext} or {@code BeanletMetaData} the context or meta
082 * data of the underlying beanlet is injected. Note that it is allowed to
083 * parameterize the target is the parameterized type is assignable from this
084 * beanlet.<br>
085 * If the target is assignable from {@code BeanletFactory} or
086 * {@code BeanletReference} the container will lookup the factory or reference
087 * of the beanlet referred to by the target. This process is described by the
088 * next paragraph - Beanlet Name Resolution. Once again, the target is allowed
089 * to be parameterized as long as the parameterized type can be assigned from
090 * the referred beanlet.
091 * </p>
092 * <p>
093 * <b>(3)</b> The final step of injectant resolution, named implicit wiring, is
094 * only executed if the {@link Wiring} annotation is applied with the
095 * appropiate wiring modes.</br>
096 * <br>
097 * There are three flavors of implicit wiring;
098 * {@code BY_INFO}, {@code BY_NAME} and {@code BY_TYPE}.<br>
099 * The {@code BY_INFO} mode is used to allow injection through the info map
100 * {@code BeanletFactory.create(Map)},
101 * {@code BeanletApplicationContext.create(String, Map)}. If the name inferred
102 * from the target is contained in the info map its value is injected.<br>
103 * For the {@code BY_NAME} mode, the container looks up the beanlet, which name
104 * is inferred from the target.<br>
105 * The final wiring mode is wiring {@code BY_TYPE}. This mode looks up a beanlet
106 * that matches the target's type. Injection only succeeds if exactly one
107 * beanlet is compliant to the target, it fails if either none or multiple
108 * beanlets are found.
109 * </p>
110 * <p>
111 * Finally, if the three previously described steps did not result in an
112 * injection, a {@link BeanletWiringException} is thrown by the application
113 * container, unless the {@link #optional} method returns {@code true}.
114 * </p>
115 *
116 * <p><h3>Beanlet Name Resolution</h3>
117 * The name of the beanlet is determined as follows:<br>
118 * <br>
119 * First, the beanlet name is extracted from the member that is to be injected.
120 * If the member is a field, the name of the field declaration is used.<br>
121 * If the member is a (setter) method, the beanlet name is derived from the
122 * method name. The beanlet name is a substring of the method name, starting at
123 * fourth character of the method name, cutting of {@code "set"}. The first
124 * character of this substring is converted to lowercase.<br>
125 * Note that it is not possible to infer a beanlet name from a constructor.<br>
126 * <br>
127 * Next, the beanlet name - previously derived from the member - is overridden
128 * if {@link #name} is set to a value other than {@code ""}.<br>
129 *
130 * <p><h3>Examples</h3>
131 * In case of the following three example classes and {@code beanlet.xml}
132 * configuration file, beanlet {@code "bar"} is injected into field {@code foo}.
133 * As a result, beanlet {@literal "example"} has a dependency on beanlet
134 * {@literal "bar"}.<br>
135 * <br>
136 * <b>(A)</b> Example of Constructor Dependency Injection:
137 * <pre>
138 * @Wiring(BY_NAME)
139 * public class Example {
140 *
141 * private final Object foo;
142 *
143 * @Inject(name="foo")
144 * public Example(Object foo) {
145 * this.foo = foo;
146 * }
147 *
148 * public void someBusinessMethod() {
149 * }
150 * }
151 * </pre>
152 *
153 * <b>(B)</b> Example of Setter Dependency Injection:
154 * <pre>
155 * @Wiring(BY_NAME)
156 * public class Example {
157 *
158 * private Object foo;
159 *
160 * @Inject
161 * public void setFoo(Object foo) {
162 * this.foo = foo;
163 * }
164 *
165 * public void someBusinessMethod() {
166 * }
167 * }
168 * </pre>
169 *
170 * <b>(C)</b> Example of Field Dependency Injection:
171 * <pre>
172 * @Wiring(BY_NAME)
173 * public class Example {
174 *
175 * @Inject
176 * private Object foo;
177 *
178 * public void someBusinessMethod() {
179 * }
180 * }
181 * </pre>
182 *
183 * <p><h3>XML Representation</h3>The following xml-fragment shows how to express this annotation in xml.<br><pre><tt><beanlets xmlns="http://beanlet.org/schema/beanlet"
184 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
185 * xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd">
186 * <beanlet name="foo" type="com.acme.Foo">
187 * <b><inject <i>field="bar"</i> name="" optional="false"
188 * value="" type="java.lang.Object" ref=""
189 * nill="false"/></b>
190 * </beanlet>
191 *</beanlets>
192 *
193 *<beanlets xmlns="http://beanlet.org/schema/beanlet"
194 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
195 * xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd">
196 * <beanlet name="foo" type="com.acme.Foo">
197 * <b><inject <i>field="bar"</i>>
198 * <value value="" type="java.lang.Object" ref=""
199 * nill="false"/>
200 * </inject></b>
201 * </beanlet>
202 *</beanlets>
203 *
204 *<beanlets xmlns="http://beanlet.org/schema/beanlet"
205 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
206 * xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd">
207 * <beanlet name="foo" type="com.acme.Foo">
208 * <b><inject <i>field="bar"</i>>
209 * <collection type="java.util.ArrayList" synced="false" unmodifiable="false">
210 * <value value="" type="java.lang.Object" ref=""
211 * nill="false"/>
212 * </collection>
213 * </inject></b>
214 * </beanlet>
215 *</beanlets>
216 *
217 *<beanlets xmlns="http://beanlet.org/schema/beanlet"
218 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
219 * xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd">
220 * <beanlet name="foo" type="com.acme.Foo">
221 * <b><inject <i>field="bar"</i>>
222 * <map type="java.util.HashMap" synced="false" unmodifiable="false">
223 * <entry>
224 * <key value="" type="java.lang.Object" ref=""
225 * nill="false"/>
226 * <value value="" type="java.lang.Object" ref=""
227 * nill="false"/>
228 * </entry>
229 * <entry key="" value=""/>
230 * </map>
231 * </inject></b>
232 * </beanlet>
233 *</beanlets>
234 *
235 *<beanlets xmlns="http://beanlet.org/schema/beanlet"
236 * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
237 * xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd">
238 * <beanlet name="foo" type="com.acme.Foo">
239 * <b><inject <i>field="bar"</i>>
240 * <beanlet name="innerFoo" type="com.acme.InnerFoo"/>
241 * </inject></b>
242 * </beanlet>
243 *</beanlets></tt></pre></p>
244 *
245 * @see Wiring
246 * @author Leon van Zantvoort
247 */
248 @Retention(RetentionPolicy.RUNTIME)
249 @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD,
250 ElementType.PARAMETER})
251 public @interface Inject {
252
253 /**
254 * {@code true} if injection is optional, {@code false} otherwise.
255 */
256 boolean optional() default false;
257
258 /**
259 * Overrides the name inferred from the marked member, unless it returns
260 * an empty string (""). How this name is used depends on the selected type
261 * of wiring.
262 */
263 String name() default "";
264
265 /**
266 * Overrides the type inferred from the marked member, unless it returns
267 * the Object class (Object.class). How this type is used depends on the
268 * selected type of wiring.
269 */
270 Class<?> type() default Object.class;
271
272 /**
273 * Returns the name of the beanlet to be injected.
274 *
275 * <p>Shortcut for {@code @Inject(@Value(ref=""))}</p>
276 */
277 String ref() default "";
278
279 /**
280 * Used to inject a value as specified by this {@code Value} annotation.
281 */
282 Value value() default @Value;
283
284 /**
285 * Used to inject a {@code Collection} or array as specified by this
286 * {@code CollectionValue} annotation.
287 */
288 CollectionValue collection() default @CollectionValue;
289
290 /**
291 * Used to inject a {@code Map} as specified by this
292 * {@code MapValue} annotation.
293 */
294 MapValue map() default @MapValue;
295 }