Advanced Wiring

Multiplicity References

Multiple target services can be injected on a reference by having the latter typed as a Collection or array:

public class SomeComponent ... {

   @Reference
   @Target("one two three")	
   protected List<SomeService> listServices;

   @Reference
   protected Set<SomeService> setServices;

   @Reference
   protected SomeService[] setServices;

}

The above references can either be autowired or explicitly wired using the Target annotation. The above example demonstrates specifying multiple targets using the Target annotation. The same configuration can be done using XML:

<component name="SomeComponent">
   <implementation.java ..../>
   <reference name="listServices" target="one two three"/>
</component>

Dynamic Wiring and Reinjection

It is important to note that multiplicity references can be dynamic. Continuing with the above example, if autowire is used and SomeComponent is deployed, it will be wired to services implementing the SomeService interface. If at some later time additional SomeService services are deployed, SomeComponent will be re-injected with the existing and new services implementing SomeService.

Similar behavior can also be achieved using explicit wiring. Reinjection will be triggered if a wire element in a composite is deployed after the source component.

Map-based Wires

It is also possible to define multiplicity references of type Map. In this case, the injected key will be defined by the target component and the value will be a proxy to the target service:

public class SomeComponent ... {

   @Reference
   protected Map<String, SomeService> services;

}

Key types can be Strings, Enums, Classes, QNames or numeric types. A key is defined in two ways. First, it can be defined as part of the target component definition using the Fabric3 'key' attribute:

<component name="SomeService" f3:key="GoldService">
   ...
</component>

In the above example, the f3 namespace maps to urn:fabric3.org.

The second method for defining a key is on the target implementation class using the Fabric3 Key annotation:

import org.fabric3.api.annotation.wire.Key;

@Key("GoldService")
public class SomeServiceImpl implements SomeService {
    ...
}

Using Keys with Bound References

An application may need to distinguish between explicitly bound target services for a multiplicity references. For example, a component may need to dispatch to one of multiple credit services depending on data such customer or loan type. This can be enabled by using a Map-based reference. Fabric3 will use the name of the binding as the Map key (in SCA, multiple bindings on a reference are required to have unique names specified):

public class SomeComponent ... {

   @Reference
   protected Map<String, CreditService> creditServices;

}
<component name="SomeComponent">
   ...
   <reference name="creditServices">
     <binding.ws name="commercial" uri="..."/>
     <binding.ws name="personal" uri="..."/>
   </reference> 
</component>

In the above example, the creditServices map will contain the keys commercial and personal, which can be used to dispatch to the correct credit service.

Ordered Injection

Components may need to be injected with an ordered collection of references. For example, a component may need to invoke a collection of processors in a particular order:

public class SomeComponent ... {

   @Reference
   protected List<Processor> processors;

   public void invoke(Message message) {
       for (Processor processor: processors){
           // processors must be invoked in order
           processor.process(message);
       }
   } 
}

Fabric3 supports ordered reference injection by using either the @Order annotation on a target component implementation or the order attribute on the target component configuration in a composite:

import org.fabric3.api.annotation.wire.Order

@Order(1)
public class CreditProcessor implements Processor {
   ...
}
<component name="CreditProcessor" order="1">
   ...
</component>

Note that the order attribute in a component configuration will override the value of an @Order annotation.