summaryrefslogtreecommitdiff
path: root/israfil-foundation-container/src/site/apt/lifecycle.apt
blob: 3a62be5000643f104f3df367431f9de97bf696df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
                                    ------
                  Israfil Micro-Container : Component Lifecycle
                                    ------
                  Christian Edward Gruber
                                    ------
                  May 2, 2007


  Since one bad pattern in java is to engage in all sorts of side behaviours 
  during construction, components can separate construction from initialization
  by implementing the Startable interface.  Startable components are started
  before they are provided to any caller.

%{toc}

The Startable interface

  The Startable interface is quite simple:
  
-------------------

package net.israfil.micro.container;

public interface Startable {
    
    public void start();
    
    public boolean isRunning();
    
}

-------------------

  Implementors should start whatever they need to in order to be ready to
  accept calls, including marshalling any resources necessary, etc.
  
  Care should be taken to time-out appropriately, as the container offers
  its thread to the component during this initialization, and faulty 
  initialization can lock the container.

Registering components with dependencies

  Registration of components with dependencies is a bit more complicated, as it
  requires an adapter:

-------------------

public void registerType(Object key, AutoWiringAdapter componentAdapter);

-------------------

  AutoWiringAdapters can be created on the fly, for instance by using an anonymous
  inner class that implements AutoWiringAdapter or extending AbstractAutoWiringAdapter:

-------------------

container.registerType(ComponentThree.class,new AbstractAutoWiringAdapter(
        ComponentThree.class, new Object[] {ComponentOne.class}
    ) {
    public Object create(Object[] params) throws IllegalAccessException, InstantiationException {
        return new ComponentThreeImpl((ComponentOne)params[0]);
    }
});

-------------------

  Another option is to create a constant adapter on the component itself

-------------------

public class ComponentThreeImpl implements ComponentThree {
    public static final AutoWiringAdapter adapter = new AbstractAutoWiringAdapter(
            ComponentThree.class, new Object[] {ComponentOne.class}
        ) {
        public Object create(Object[] params) throws IllegalAccessException, InstantiationException {
            return new ComponentThreeImpl((ComponentOne)params[0]);
        }
    });
    
    private final ComponentOne one;
    
    public ComponentThreeImpl(ComponentOne one) {
        this.one = one;
    }
    
    public void doStuff() { one.whatever(); }
}

-------------------

  Having created this adapter constant, you can then more easily register the 
  component in the following way:
  
-------------------

container.registerType(ComponentThree.class,ComponentThreeImpl.adapter);

-------------------

Retrieving components

  Retrieving components is quite simple, using the getComponent method.  
  
-------------------

ComponentThree three = (ComponentThree)container.getComponent(ComponentThree.class);
three.doStuff();

-------------------