Previous Topic

Next Topic

Book Contents

Book Index

Using the Component Factory Service

A document illustrating the steps for using the Component Factory service.

To use the Component Factory service:

  1. Define the component you want to produce multiple instances of as a factory component. To define a component as a factory component, declare a factory="<factory_name>" attribute in the component element of its description.
  2. Declare component properties in the component's description that will be passed to the Component Factory service when creating new instances of the same component type. Component properties are declared in property or properties elements as described in the "Component Description Elements" section.
  3. Get the Component Factory OSGi service and call its newInstance method by providing some custom properties.

The Component Factory, that the SCR creates and associates with the component definition, can create multiple instances if the component is satisfied. If the a factory component's dependencies are not met, the component is disposed and the Component Factory service is unregistered.

If the factory component is supposed to provide a service, a service object will be registered on its behalf each time the newInstance method of the associated ComponentFactory is called.

Following is the implementation class of a factory component that provides the Hello Service introduced in the Providing a Service section. For simplicity, the service's hello method is called in the component's activate method:

Listing 1. The implementation class of the Hello Service.

package simple.service.impl;

import org.osgi.service.component.ComponentContext;
import simple.service.HelloService;

public class HelloServiceImpl implements HelloService {

  ComponentContext context;
    
  protected void activate(ComponentContext ctxt){
     this.context = ctxt;
    
     hello();      
  }
    
  public void hello() {
        
     System.out.println("Hello components!");
  }
    
  protected void deactivate(ComponentContext ctxt){
     this.context = null;
}
}  

And the component description where the component is declared as a factory component:

Listing 2. A component description of a factory component.

<?xml version="1.0" encoding="UTF-8"?>
<scr:component name="HelloComponentFactory" factory="hello.component.factory"
xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
  <implementation class="simple.service.impl.HelloServiceImpl"/>
  <service>
      <provide interface="simple.service.HelloService"/>
  </service>
  <property name="Prop1" value="init value"/>
  <property name="Prop2" type="Integer" value="0"/>
</scr:component>
          

The next example is a component which gets the Component Factory service and creates an instance of the factory component from the previous example:

Listing 3. Creating a factory component instance

package simple.component.factory;

import java.util.Hashtable;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.ComponentFactory;
import org.osgi.service.component.ComponentInstance;
public class HelloComponentFactoryRef {
    
   ComponentContext context;
   ComponentFactory factory;
   ComponentInstance compInstance;
   Hashtable factoryProps;

   public void setFactory(ComponentFactory cmpFact){
    
      this.factory = cmpFact;
      factoryProps = new Hashtable();
      factoryProps.put("Prop1","new value");
      factoryProps.put("Prop2",new Integer(20));
            
      compInstance = factory.newInstance(factoryProps);
   }
        
   public void unsetFactory(ComponentFactory cmpFact){
      
      this.factory = null;
   }

}

The next listing contains the component description of the SimpleComponentFactoryRef component. Its reference element includes a target attribute who's value is an LDAP filter that constrains the referenced Component Factory services to the one associated with the SimpleComponent component. The filter is in (component.factory=<component factory name>) format.

Listing 4. The HelloComponentFactoryRef component description

<?xml version="1.0" encoding="UTF-8"?>
<scr:component name="HelloComponentFactoryRef" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.0.0">
  <implementation class="simple.component.factory.HelloComponentFactoryRef"/>
  <reference name="ComponentFactoryRef"
     interface="org.osgi.service.component.ComponentFactory"
     bind="setFactory"
     unbind="unsetFactory"
     target="(component.factory=hello.component.factory)"
  />
</scr:component>