iPOJO Factories PrinciplesIPOJO iPOJO defines a factory for each declared component type. These factories are used to create component instances. This document presents component type and component instance conceptshow to declare instances inside iPOJO metadata, and how-to use factories is a metadata file and with the APIcreate, dispose and reconfigure dynamically instances. Note: This page refers on iPOJO 0.8.0 and iPOJO 0.9.0-SNAPSHOT features. Preliminary ConceptsComponent TypeA component type is a kind of instance template. If we compare component concepts with object oriented programming, component types are classes and component instances are objects. A component type is declared inside a metadata file (generally named 'metadata.xml'). The next snippet shows you a component type declaration: | Code Block |
|---|
|
<component className="..." factoryname="MyFactory">
...
<!â€"handler--component type configuration - ->
...
</component>
|
A component type is generally declaration begins generally by '<component>' and is composed by: - An implementation class ('className', mandatory)
- A factory name (factory'name')
- Handlers Handler configuration (see handler guide)
The 'name' attribute contains the factory attribute contains name. If not specified, the 'className' attribute is used as the factory name. This factory name is used to refer to the factory (and consequently to the component type). The A factory attribute configuration can varies - The factory attribute contains a name: this name will be used as factory name.
- The factory attribute contains "no" : the factory will be private
- The factory attribute is not declared: the class name is used as factory name.
be public or private. A public factory allows creating instances dynamically and from other bundles. A private factory can only be used to create instances declared in the same metadata than the component type (i.e. in the same bundle). By default, factories are public. To set the factory to private add the 'public="false"'' attribute in the '<component>' element, such as: | Code Block |
|---|
|
<component className="..." name="MyPrivateFactory" public="false">
...
<!--component type configuration -->
...
</component>
|
Public factories offer different way to create instances: - Instances can be declared in iPOJO descriptor in any bundle
- Instances can be created dynamically by using the API
A private factory is no accessible outside the metadata file. To refer to the type, you need to use the class name. If the factory is public (not private), the factory is accessible outside the metadata file. Indeed, iPOJO will publish two services to access to the factory through the API: - org.apache.felix.ipojo.Factory : iPOJO Factory Interface
- org.osgi.service.cm.ManagedServiceFactory : Config Admin Interface
The factory name will be used a service.pid property for these services. The service.pid is unique and persists between frmaework restarts.framework restarts. The service.pid of the factory equals the factory name. Factories are either valid or invalid. You can't create instances until a factory becomes valid. A factory is invalid if required handlers are missing. This issue occurs only if the component type uses external handlers. Component InstanceA component instance is an instance of a component type. For example, if a component type declares providing and requiring services, the component instances, will expose and require really those services. Each factory can create several instancesSeveral instances can be created from one factory, but all these instances will be managed as different entities, and will be so are independent. A component instance is characterized by: - a component type (the factory name)
- an instance name (used to identify the instance, is unique)
- a configuration : a set of properties ( <key, value> )couple
A factory keeps a reference on each instance it createscreated instances. If the factory stops or , goes away, or becomes invalid, all created instances stops are stopped and will be are destroyed. To create an instance, the instance declaration gives the name and the configuration to the factory. However, the must refer to the factory (by using the factory name), and provide the instance configuration. This configuration can specify the instance name ('instance.name' property). Be aware that this name must be unique. If not specified, iPOJO will generate a unique name. A factory can refuse the creation if the configuration is not acceptable or if the factory is invalid. An unacceptable configuration is a configuration not suitable with the configuration in regard to component type. Reasons for unacceptable configuration are: - the The instance name is not set or not unique
- a property lacks A property required by the component type is missing inside the configurationa property value cannot be transform in the property
- A pushed property has a wrong type
A metadata file can declare instances from private (and contained) component type and from public (contained or not) factories. If a component type is private (factory attribute of the component type is "no"), the metadata file is the only way to create instances for this type. It is generally used when the component instance must be the unique instance of the type. Else, component instance can be declared either in the metadata file declaring the type, either in an external metadata file. If a declared instance targets an outside factoryThe main way to create instances is to declare those instances inside the iPOJO descriptor file (i.e. 'metadata.xml'). Those declarations can use either public factories from any bundle, or private factories from the same bundle. Private factories are generally used to guaranty singleton instance as instances can only be created inside the same bundle. When a instance declaration targets an external public factory, it will wait until the factory becomes available. So, the instance will be created only when the factory appears and is availablevalid. Then, if If the factory goes away, disappears after the instance stopscreation, but if the factory comes back, the instance instance is disposed and will be recreated as soon as the factory comes back. The next snippet shows how to declare an instance in the metadata: | Code Block |
|---|
|
<instance component="component factory name" name = "instance name" >
<property name="a property name" value="a string form of the value"/>
<property name="another propertyprop name" value="the string form ofvalue the wanted value"/>
</instance>
|
The component type attribute contains the targeted factory An instance declaration must contain the 'component' attribute. This attribute specifies the factory name (i.e. the component type). It can use either the factory name or the class name. The 'name' attribute declares allows setting the instance name. If not set, iPOJO will generate a unique name for you. Then, instances can declare properties. Those property are mostly key-value pair. The key refer to a property name from the component type declaration such as in: | Code Block |
|---|
|
<component className="..." name="my-factory">
<properties>
<property name="foo" field="m_foo"/>
</properties>
</component>
<instance component="my-factory ">
<property name="foo" value="bla bla bla"/>
</instance>
|
The string-form of the property value will be use to create the real object at runtime. The instance configuration is set by declaring a set of properties. A property is composed by a name and a value. The value is the string form of the wanted value. The iPOJO runtime will create the property object with this string. If an unacceptable configuration is set, the instance is not created, and an error message appears to the console (and in the Log Service if present).
How-to use iPOJO factory serviceA public factory is exposed as an org.apache.felix.ipojo.Factory service. This service is accessible as any other OSGiâ„¢ service, and could be an iPOJO dependency too. This service used the following interfaces: | Code Block |
|---|
|