org.beanlet
Annotation Type Inject


@Retention(value=RUNTIME)
@Target(value={CONSTRUCTOR,METHOD,FIELD,PARAMETER})
public @interface Inject

Members marked with this annotation are injected by the application container during beanlet instance creation.

Dependency injection is supported for all member types - constructors, methods, and fields. Constructor dependency injection is used for injecting one or more objects into the constructor of a beanlet, resulting in a new beanlet instance. Alternatively, beanlet instances can be created by a (static) factory method. This factory method may defined by any class. Only one constructor or factory method may be marked with this annotation to avoid ambiguoutiy.

Setter dependency injection is applied to all fields and (non-static) methods that are marked with this annotation.

Dependency injection is performed before any lifecycle methods are invoked on the beanlet instance. All members that are marked for (non-optional) dependency injection are guaranteed to be injected, otherwise beanlet instance creation fails.

Injectant Resolution

This section explains the process of finding the object to be injected - further referred to as injectant - for a member that is target to dependency injection. The following steps are performed by the application container in listed order.

(1) First step is explicit dependency injection. The Inject annotation specifies a value to be injected through the value(), collection() or map() methods.

(2) The container performs step two of injectant resulution if and only if step one does not result in an injectant. During step two the container checks if the member to be injected expresses a framework class. These classes include: BeanletApplicationContext, BeanletContext, BeanletMetaData, BeanletFactory and BeanletReference. If the target matches BeanletApplicationContext the instance returned by BeanletApplicationContext.instance() is injected. If the target matches BeanletContext or BeanletMetaData the context or meta data of the underlying beanlet is injected. Note that it is allowed to parameterize the target is the parameterized type is assignable from this beanlet.
If the target is assignable from BeanletFactory or BeanletReference the container will lookup the factory or reference of the beanlet referred to by the target. This process is described by the next paragraph - Beanlet Name Resolution. Once again, the target is allowed to be parameterized as long as the parameterized type can be assigned from the referred beanlet.

(3) The final step of injectant resolution, named implicit wiring, is only executed if the Wiring annotation is applied with the appropiate wiring modes.

There are three flavors of implicit wiring; BY_INFO, BY_NAME and BY_TYPE.
The BY_INFO mode is used to allow injection through the info map BeanletFactory.create(Map), BeanletApplicationContext.create(String, Map). If the name inferred from the target is contained in the info map its value is injected.
For the BY_NAME mode, the container looks up the beanlet, which name is inferred from the target.
The final wiring mode is wiring BY_TYPE. This mode looks up a beanlet that matches the target's type. Injection only succeeds if exactly one beanlet is compliant to the target, it fails if either none or multiple beanlets are found.

Finally, if the three previously described steps did not result in an injection, a BeanletWiringException is thrown by the application container, unless the optional() method returns true.

Beanlet Name Resolution

The name of the beanlet is determined as follows:

First, the beanlet name is extracted from the member that is to be injected. If the member is a field, the name of the field declaration is used.
If the member is a (setter) method, the beanlet name is derived from the method name. The beanlet name is a substring of the method name, starting at fourth character of the method name, cutting of "set". The first character of this substring is converted to lowercase.
Note that it is not possible to infer a beanlet name from a constructor.

Next, the beanlet name - previously derived from the member - is overridden if name() is set to a value other than "".

Examples

In case of the following three example classes and beanlet.xml configuration file, beanlet "bar" is injected into field foo. As a result, beanlet "example" has a dependency on beanlet "bar".

(A) Example of Constructor Dependency Injection:
 @Wiring(BY_NAME)
 public class Example {
     
     private final Object foo;

     @Inject(name="foo")
     public Example(Object foo) {
         this.foo = foo;
     }

     public void someBusinessMethod() {
     }
 }
 
(B) Example of Setter Dependency Injection:
 @Wiring(BY_NAME)
 public class Example {
     
     private Object foo;

     @Inject 
     public void setFoo(Object foo) {
         this.foo = foo;
     }

     public void someBusinessMethod() {
     }
 }
 
(C) Example of Field Dependency Injection:
 @Wiring(BY_NAME)
 public class Example {
     
     @Inject 
     private Object foo;

     public void someBusinessMethod() {
     }
 }
 

XML Representation

The following xml-fragment shows how to express this annotation in xml.
<beanlets xmlns="http://beanlet.org/schema/beanlet"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd">
  <beanlet name="foo" type="com.acme.Foo">
    <inject field="bar" name="" optional="false" 
            value="" type="java.lang.Object" ref="" 
            nill="false"/>
  </beanlet>
</beanlets>
 
<beanlets xmlns="http://beanlet.org/schema/beanlet"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd">
  <beanlet name="foo" type="com.acme.Foo">
    <inject field="bar">
      <value value="" type="java.lang.Object" ref="" 
             nill="false"/>
    </inject>
  </beanlet>
</beanlets>

<beanlets xmlns="http://beanlet.org/schema/beanlet"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd">
  <beanlet name="foo" type="com.acme.Foo">
    <inject field="bar">
      <collection type="java.util.ArrayList" synced="false" unmodifiable="false">
        <value value="" type="java.lang.Object" ref="" 
               nill="false"/>
      </collection>
    </inject>
  </beanlet>
</beanlets>

<beanlets xmlns="http://beanlet.org/schema/beanlet"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd">
  <beanlet name="foo" type="com.acme.Foo">
    <inject field="bar">
      <map type="java.util.HashMap" synced="false" unmodifiable="false">
        <entry>
          <key value="" type="java.lang.Object" ref="" 
               nill="false"/>
          <value value="" type="java.lang.Object" ref="" 
                 nill="false"/>
        </entry>
        <entry key="" value=""/>
      </map>
    </inject>
  </beanlet>
</beanlets>

<beanlets xmlns="http://beanlet.org/schema/beanlet"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://beanlet.org/schema/beanlet http://beanlet.org/schema/beanlet/beanlet_1_0.xsd">
  <beanlet name="foo" type="com.acme.Foo">
    <inject field="bar">
      <beanlet name="innerFoo" type="com.acme.InnerFoo"/>
    </inject>
  </beanlet>
</beanlets>

See Also:
Wiring

Optional Element Summary
 CollectionValue collection
          Used to inject a Collection or array as specified by this CollectionValue annotation.
 MapValue map
          Used to inject a Map as specified by this MapValue annotation.
 String name
          Overrides the name inferred from the marked member, unless it returns an empty string ("").
 boolean optional
          true if injection is optional, false otherwise.
 String ref
          Returns the name of the beanlet to be injected.
 Class<?> type
          Overrides the type inferred from the marked member, unless it returns the Object class (Object.class).
 Value value
          Used to inject a value as specified by this Value annotation.
 

optional

public abstract boolean optional
true if injection is optional, false otherwise.

Default:
false

name

public abstract String name
Overrides the name inferred from the marked member, unless it returns an empty string (""). How this name is used depends on the selected type of wiring.

Default:
""

type

public abstract Class<?> type
Overrides the type inferred from the marked member, unless it returns the Object class (Object.class). How this type is used depends on the selected type of wiring.

Default:
java.lang.Object.class

ref

public abstract String ref
Returns the name of the beanlet to be injected.

Shortcut for &#64;Inject(&#64;Value(ref=""))

Default:
""

value

public abstract Value value
Used to inject a value as specified by this Value annotation.

Default:
@org.beanlet.Value

collection

public abstract CollectionValue collection
Used to inject a Collection or array as specified by this CollectionValue annotation.

Default:
@org.beanlet.CollectionValue

map

public abstract MapValue map
Used to inject a Map as specified by this MapValue annotation.

Default:
@org.beanlet.MapValue


Copyright © 2006-2012. All Rights Reserved.