Include Page | ||||
---|---|---|---|---|
|
HTML |
---|
<div class="content">
|
Declaring component types
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component
classname="my.Implementation"
name="my-type"
>
</component>
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component(name="my-type") public class Implementation { // ... } |
Div | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||
|
...
Creating component instances
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<instance component="my-type"/>
<instance component="my.Implementation"/>
<instance component="my-type" name="my-instance"/>
<instance component="my-type" name="my-instance">
<property name="property1" value="value1"/>
</instance>
</component>
| ||||||
Center | ||||||
Div | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||
|
- Instances can contains a configuration given under the
key-value
form. Properties can also by complex type (refer to . - How-to use iPOJO factories
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component(name="my-type") |
...
@Instantiate
public class Implementation {
// ...
}
|
Providing services
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component classname="my.service.implementation" name="my-service-impl"> <provides/> </component> <instance name="my-service-impl"/> |
...
- Only instances provides really services, so don't forget to declare an instance.
- Published service interfaces must be implemented by your component implementation
Div class borderedTable Center Attribute name
Required
Default value
specifications
no
all implemented interfaces
specifies the published service interfaces
strategy
no
singleton
specifies the service object creation policy among
singleton
,service
(OSGi Service Factory),method
(use the factory method),instance
(an object per instance) - Providing OSGi services
Publishing service properties
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component @Provides(specifications= {FooService.class, BarService.class}, properties= { @StaticServiceProperty(name="baz", type="java.lang.String")}) public class ProvidesProperties implements FooService, BarService { @ServiceProperty(name = "foo") public int m_foo = 0; @ServiceProperty(name="bar", mandatory=true) public int m_bar; // ... } |
Div | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||||
|
Using services with field injection
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component classname="my.consumer.Implementation">
<requires field="fs" />
<requires field="bs" />
</component>
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component
public class Dependency {
@Requires
public FooService fs;
@Requires
public BarService[] bs;
//...
}
|
Div | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Using services with method injection
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component classname="my.consumer.Implementation">
<requires>
<callback type="bind" method="bind" />
<callback type="unbind" method="unbind" />
<callback type="modified" method="modified" /> <!-- for filtered service dependencies, to be notified when a service is modified but still match -->
</requires>
</component>
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component
public class Dependency {
@Unbind
public synchronized void unbindBaz(BazService bz) {
//...
}
@Bind
public synchronized void bindBaz(BazService bz) {
// ...
}
@Modified
public synchronized void modifiedBaz() {
// ...
}
//...
}
|
Div | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Configuring service dependencies in the instance configuration
Configuring the from
attribute
- Thanks to the
requires.from
property, it is possible to override thefrom
attribute value.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component
classname="...MyComponent"
name="FOO">
<requires field="m_foo" id="id1">
<callback type="bind" method="bind"/>
<callback type="unbind" method="unbind"/>
</requires>
</component>
<instance name="FOO1" component="FOO"/> <!-- Use the default 'from' value -->
<instance name="FOO2" component="FOO">
<property name="requires.from">
<property name="id1" value="myprovider"/>
</property>
</instance>
|
Configuring the filter
attribute
- Thanks to the
requires.filters
property, it is possible to override thefilter
attribute value.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component
classname="org.apache.felix.ipojo.example.FilteredDependency"
name="FOO">
<requires field="m_foo" fiter="(foo.property=FOO)" id="id1">
<callback type="bind" method="bind"/>
<callback type="unbind" method="unbind"/>
</requires>
</component>
<instance name="FOO1" component="FOO"/> <!-- Use the default 'filter' value -->
<instance name="FOO2" component="FOO">
<property name="requires.filters">
<property name="id1" value="(foo.property=BAR)"/>
</property>
</instance>
|
Reacting to lifecycle state changes
Immediate components
- A POJO object (implementation object) is created as soons as the instance becomes valid
- Instances that don't provide services becomes automatically immediate
Code Block xml xml title XML <component classname="my.service.implementation" name="my-service-impl" immediate="true"> <provides/> </component>
Code Block java java title Annotations @Component(immediate=true) @Provides public class Implementation implements FooService { ... }
Div class borderedTable Center Attribute name
Required
Default value
immediate
no
false // true for instances that don't provide a service
specifies if the instance is immediate or not
- Lifecycle Callback Handler
Lifecycle callbacks
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component classname="my.implementation" name="my-impl">
<callback transition="validate" method="start" />
<callback transition="invalidate" method="stop" />
</component>
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component public class Implementation { @Validate public void start() { } @Invalidate public void stop() { } } |
Declaring properties
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<component classname="my.Implementation" name="my-impl"> <properties propagation="true" managedservice="MyPID"> <property name="boo" method="setBoo" /> <property field="m_bar" mandatory="true"/> <property field="m_foo" value="4"/> </properties> </component> <instance component="my-impl"> <property name="boo" value="..."/> <property name="m_bar" value="..."/> </instance> <instance component="my-impl"> <property name="boo" value="..."/> <property name="m_bar" value="..."/> <property name="managed.service.pid" value="AnotherPID"/> </instance> |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component(managedservice="MyPID", propagation=true) public class Implementation { @Property(name="boo") public void setBoo(int boo) { //... } @Property(mandatory=true) public int m_bar; @Property(value="4") public int m_foo; } |
Div | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||||||
|
PostRegistration and PostUnregistration callbacks
- This feature is part of the provided service handler, and so requires that the component provides a service.
- The callback receives a
ServiceReference
as parameter.Code Block xml xml title XML <component classname="..."> <provides post-unregistration="unregistered" post-registration="registered"/> </component>
Code Block java java title Annotations @PostRegistration public void registered(ServiceReference ref) { System.out.println("Registered"); } @PostUnregistration public void unregistered(ServiceReference ref) { System.out.println("Unregistered"); }
- Provided Service Handler
Controlling service publication
- This feature is part of the provided service handler, and so requires that the component provides a service.
- It allows a component to force the un-publication of a service.
Code Block xml xml title XML <component classname="..."> <provides> <controller field="controller" value="false"/> </provides> </component>
Code Block java java title Annotations @ServiceController(value="false") private boolean controller
- Provided Service Handler
Using 'arch'
- Deploy the 'arch' command bundle (available for Felix and Equinox)
- Launch the 'arch' command in the OSGi Framework Shell
Code Block java java title Felix Shell arch => displays instances name & state (equivalent to arch \-instances) arch -instance $instance_name => displays complete information about the instance $instance_name arch -factories => display the list of available factories arch -factory $factory_name => display complete information about the factory $factory_name arch -handlers => list available handlers
Code Block java java title Felix Gogo ipojo:instances => displays instances name & state (equivalent to arch \-instances) ipojo:instance $instance_name => displays complete information about the instance $instance_name ipojo:factories => display the list of available factories ipojo:factory $factory_name => display complete information about the factory $factory_name ipojo:handlers => list available handlers
Temporal Dependencies
- Temporal dependencies are injected in fields. When accessing to the service, the thread waits for the service availability. If a timeout is reached, a timeout policy is executed.
- Service objects can be injected as
proxies
and be given to collaborator objects. - Temporal dependencies are implemented as an external handlers. To use them, deploy and start the temporal dependency handler bundle.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<iPOJO xmlns:temporal="org.apache.felix.ipojo.handler.temporal">
<component
className="my.Implementation">
<!-- Temporal dependency configuration -->
<temporal:requires field="mytemporal"/>
<provides/>
</component>
</iPOJO>
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
import org.apache.felix.ipojo.annotations.Component;
import org.apache.felix.ipojo.handler.temporal.Requires;
import org.apache.felix.ipojo.test.scenarios.annotations.service.FooService;
@Component
public class Implementation {
@Requires // org.apache.felix.ipojo.handler.temporal.Requires
private FooService mytemporal;
}
|
Div | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||
|
Sending and receiving events
Receiving events
- The event admin handler allows receiving events from the Event Admin.
- The event admin handler is implemented as an external handlers. To use it, deploy and start the event admin handler bundle and an implementation of the event admin service.
- Event (or data) are receive thanks to a callback method.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<ipojo
xmlns:ev="org.apache.felix.ipojo.handlers.event.EventAdminHandler">
<component className="...MyComponent">
<ev:subscriber
name="mySubscriber"
callback="receive"
topics="foo"/>
</component>
</ipojo>
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component
public class MyComponent {
@Subscriber(name="s1", data_key="data")
public void receive1(Object foo) {
// Nothing
}
@Subscriber(name="s2", topics="foo,bar", filter="(foo=true)")
public void receive2(Event foo) {
// Nothing
}
@Subscriber(name="s3", topics="foo", data_key="data", data_type="java.lang.String")
public void receive3(String foo) {
// Nothing
}
|
Div | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||||||
|
- Instance configuration
- event.topics : overrides
topics
attribute - event.filter : overrides
filter
attribute
- event.topics : overrides
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<instance component="...MyComponent"> <property name="event.topics"> <property name="mySubscriber" value="foo"/> </property> <property name="event.filter"> <property name="mySubscriber" value="|((arg=Minibar)(arg=Coconuts))"/> </property> </instance> |
Sending events
- The event admin handler allows sending events to the Event Admin.
- The event admin handler is implemented as an external handlers. To use it, deploy and start the event admin handler bundle and an implementation of the event admin service.
- To send events, your code must contains a
org.apache.felix.ipojo.handlers.event.publisher.Publisher
field.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<ipojo xmlns:ev="org.apache.felix.ipojo.handlers.event.EventAdminHandler"> <component className="...MyComponent"> <ev:publisher name="myPublisher" field="m_publisher" topics="bar,nuts"/> </component> <instance component="...MyComponent"/> </ipojo> |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component public class MyComponent { // We use qualified names to avoid conflict. @org.apache.felix.ipojo.handlers.event.Publisher(name="p1", synchronous=true) org.apache.felix.ipojo.handlers.event.publisher.Publisher publisher1; @org.apache.felix.ipojo.handlers.event.Publisher(name="p2", synchronous=false, topics="foo,bar", data_key="data") org.apache.felix.ipojo.handlers.event.publisher.Publisher publisher2; @org.apache.felix.ipojo.handlers.event.Publisher(name="p3", synchronous=true, topics="bar") org.apache.felix.ipojo.handlers.event.publisher.Publisher publisher3; // ... public void doSomething() { Dictionary e = new Properties(); //... // Fill out the event // Send event publisher1.send(e); } } |
Div | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||||||||||
|
- Instance configuration
- event.topics : overrides
topics
attribute
- event.topics : overrides
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<instance component="...MyComponent">
<property name="event.topics">
<property name="myPublisher" value="foo"/>
</property>
</instance>
|
Extender Pattern
- Allows implementing an
Extender pattern
without handling obscure details - The extender pattern handler is implemented as an external handlers. To use it, deploy and start the external pattern handler bundle.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<ipojo xmlns:extender="org.apache.felix.ipojo.extender">
<component
classname="org.apache.felix.ipojo.extender.Myextender">
<!—Extender Pattern handler configuration -->
<extender:extender
extension="My-Extension"
onArrival="onArrival"
onDeparture="onDeparture"
/>
<callback transition="invalidate" method="stopping" />
<callback transition="validate" method="starting" />
</component>
</ipojo>
|
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component
@org.apache.felix.ipojo.extender.Extender(extension="My-Extension", onArrival="onArrival", onDeparture="onDeparture")
public class Myextender {
public void onArrival(Bundle bundle, String extension) {
// handle matching bundle arrival
}
public void onDeparture(Bundle bundle) {
// handler matching bundle departure
}
}
|
Div | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||||||||||
|
Whiteboard Pattern
- Allows implementing a
Whiteboard pattern
without handling obscure details - The whiteboard pattern handler is implemented as an external handlers. To use it, deploy and start the whiteboard pattern handler bundle.
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
<ipojo xmlns:wbp="org.apache.felix.ipojo.whiteboard"> <component classname="org.apache.felix.ipojo.test.MyWhiteBoardPattern" > <wbp:wbp filter="(my.property=1)" onArrival="onArrival" onDeparture="onDeparture" onModification="onModification" /> <provides/> </component> |
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
@Component @org.apache.felix.ipojo.whiteboard.Wbp(filter="(my.property=1)", onArrival="onArrival", onDeparture="onDeparture", onModification="onModification") public class WhiteBoardWIModification { public void onArrival(ServiceReference ref) { // ... } public void onDeparture(ServiceReference ref) { // ... } public void onModification(ServiceReference ref) { // ... } } |
Center | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
- White Board Pattern Handler
Include Page apache-felix-ipojo-footer apache-felix-ipojo-footer