Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The lifecycle callback handler allows invoking methods (callbacks) on the instance when instance's state changed. For example, it allows invoking a start method when the instance becomes valid and a stop method when the instance becomes invalid. Moreover, this handler allows the creation of immediate component. This page presents how to use this handler.

Instance Lifecycle

iPOJO instances have a very simple lifecycle. This lifecycle contains two states: INVALID and VALID. Once an instance is created, this instance can only be valid if all its plugged handlers are valid. For example, an instance requiring a service (and so using the dependency handler) cannot be valid if the required service is unavailable. Indeed, the dependency handler will be invalid.

An instance starts and stops in the invalid state.

<IMAGE>

Lifecycle callback

This handler supports two kinds of callback. The INVALID=>VALID callback are invoked when the instance becomes valid (at starting or when an event allows the instance to become valid). The VALID=>INVALID callback are invoked when the instance becomes invalid (at stopping or when an event invalids the instance).

<IMAGE>

An example

Let's take an example. The following class requires a FooService and has two lifecycle callback start and stop.

Code Block

public class Foo {
              FooService fs;              private void start() {
  

Lifecycle Callback handlers

The Lifecycle Callback Handler manage callbacks on the component when the component state changes.

Lifecycle Callbacks

The lifecycle callbacks allow calling methods when the component state changed. You can use this features if your component need to do some actions when it becomes valid (for example create and launch a thread) or need to do some actions when it becomes invalid (for example stop the thread).

Component lifecycle transition

Image Removed

iPOJO components have two states: VALID and INVALID The state is valid when all handlers are valid. The state becomes invalid when one or more handlers are not valid. The next figure shows the component states automata. When you use the iPOJO standard component model, the only handler interfering with the component state is the dependencies. Consequently, a component is valid when all its dependencies are valid, and a component is invalid when one or several dependencies are invalid.

Lifecycle Callback Metadata

The next figure shows the lifecycle callbacks metadata.
Image Removed

A callback owns a method and describes the transition on which the method should be called. The initial and final attributes defines the initial and the final state of the transition. So the value can be either VALID either INVALID The method attribute contains the name of the method to call. The last attribute is optional. isStatic is "true" when the method is a static method. By default, isStatic is "false".

Examples

Source code

The following code shows you a component with two callbacks: starting and stopping.

Code Block

 package fr.imag.adele.escoffier.hellorequester.impl;

 import fr.imag.adele.escoffier.hello.HelloService;

 public class HelloRequesterImpl implements Runnable {

    final static int DELAY=10000;
    HelloService[] m_hello;  // Service Dependency
    boolean end;

    public void run() {
        while (!end) {
           // tryStarting {
method
                    synchronized (this) { {//...
                for(int  i = 0; i < m_hello.length; i++) {fs.foo();
                        System//.out.println(m_hello[i].sayHello("Clement"));

                }        }
        }
              protected void Thread.sleepstop(DELAY);
 {
                        }// catch (InterruptedException ie) {Stopping method
			if(fs!=null) { fs.foo(); }
                /* will recheck quit */}}

For this class, we define the following component type:

Code Block
xml
xml

<component className="...Foo">
       <dependency field="fs"/>
       <callback initial="INVALID" final="VALID" method="start"/>
  }
     <callback initial="VALID" final="INVALID" method="stop"/>
</component>

When an instance of this component type is created, the start method is called as soon as the Foo Service (service dependency) becomes available. If the Foo Service is no more available or when the instance is stopped, the stop method is called.

The invoked methods have no argument, but could be private, protected or public. Moreover, the INVALID=>VALID method can use service dependency (the instance becomes valid means that all required services are available); however, in the stop method it is possible that one of these dependency can be null. Indeed, the departure of a service can be the cause of the instance invalidation.

Manage threads

One usage of lifecycle callback is when the instance needs to create threads. Indeed, the thread can be created in the INVALID=>VALID callback, and stopped in the VALID=>INVALID method. The next class shows an example of a class creating a thread.

Code Block

public class HelloRequesterImpl implements Runnable {

&nbsp;&nbsp;&nbsp; final static int DELAY=10000;
&nbsp;&nbsp;&nbsp; HelloService\[\] m_hello;&nbsp; // Service Dependency
&nbsp;&nbsp;&nbsp; boolean end;

&nbsp;&nbsp;&nbsp; }
    }
   
    public void startingrun() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (\!end) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized (this) {  Thread T = new Thread(this);
        end = false;
        T.start();
    }
   
   {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i = 0; i < m_hello.length; i++) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(m_hello\[i\].sayHello("Clement"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep(DELAY);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (InterruptedException ie) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /\* will recheck quit \*/
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp;&nbsp; }
&nbsp; &nbsp;
&nbsp;&nbsp;&nbsp; public void starting() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread T = new Thread(this);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end = false;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; T.start();
&nbsp;&nbsp;&nbsp; }
&nbsp; &nbsp;
&nbsp;&nbsp;&nbsp; public void stopping() { end = true; }

XML Metadata

Hence, XML-metadata associated with this component need to contain:

For this component type, the metadata should be :

Code Block
xml
xml

<component className="... HelloRequesterImpl">
		<dependency field="HelloService"/>
		<callback 
Panel
<Callback
initial="INVALID" final="VALID" method="starting"/>

<Callback

		<callback initial="VALID" final="INVALID" method="stopping"/>

Manifest Metadata

The manifest-metadata associated with this component need to contain:

Panel

Callback { $initial=INVALID $final=VALID $method=starting }
Callback { $initial=VALID $final=INVALID $method=stopping }

Component Instance Creation

When a non-static "starting" callback is called, it needs a component instance. Therefore, the callback asks the component manager to create an instance. Each callback and each singleton provided service would use this instance.

Callback on multi-component instance

When several instance of the component are created, the callback are called on each instance in the creation order.

Limitation and perspectives


</component>

Immediate component

An instance of an immediate component type is instantiated as soon it becomes valid. It means that, when the instance becomes valid, the constructor of the implementation class is called. This can replace the INVALID=>VALID callback.

<IMAGE>

However as there is no destructor in Java, the VALID=>INVALID callback is necessary if some actions are needed when stopping.

Advanced features

Static callbacks

You can call a static method as a callback. By default, the callback is not static. To call a static method, you need to add the isStatic attribute in the callback metadata :

Code Block
xml
xml

<callback initial="INVALID" final="VALID" method="start" isStatic="true"/>
<callback initial="VALID" final="INVALID" method="stop" isStatic="true/>

Callback on several objects

If you instance has created several objects (called the implementation class constructor several times), the callback is called on each object in the creation order.  The main limitation of the lifecycle callbacks is that the component lifecycle is very small. Therefore, we are thinking about how extends the component lifecycle with extensible and customizable lifecycle.