|
|||||
|
|||||
Lifecycle
Why Lifecycle?Life cycle support is an important aspect of an IOC container because objects contained in the container may sometimes demand life-cycle transitions such as "start", "stop", "init", "dispose" etc. These transition phases should respect the dependency between objects so that an object is not "initialized" until all objects it depends on are already "initialized" and it is "disposed" before any object it depends on gets disposed. Life evolves, not develops.Yan's life cycle support is provided as an add-on package. There's no special facility in the core designed with lifecycle in mind. Yet, this life cycle support naturally evolved from using the general purpose combinators provided by the core. This means, you can always come up with your own life-cycle library if you don't opt to use or extend this life cycle package. Lifecycle support in Yan does not require the components to be singleton. Any component can be managed by lifecycle manager. Make them aliveNow let's discuss some details about the out-of-box life cycle package. In order to manage lifecycle for components, a LifecycleManager needs to be created: DefaultLifecycleManager man = new DefaultLifecycleManager();
Then, to define a life-cycle for a component, we need to create a Lifecycle object: DefaultLifecycleManager.DefaultLifecycle life = man.newLifecycle()
.initializer("init)
.disposer("destroy")
.starter("start")
.stopper("stop");
The above code creates a Lifecycle object with 4 phases: init, dispose, start, stop. Each phase is associated with a method name so that init(), destroy(), start(), stop() are executed for each phase. The Lifecycle object can then be associated with any Component that wishes to have such lifecycle defined. As a metaphore, any component can be given life: Component automobile = Components.ctor(Automobile.class); Component live_automobile =life.manage(automobile); This live automobile along with many other live or non-live components can be registered to containers and instantiated: Container yan = ...; yan.registerComponent("auto", live_automobile); yan.registerComponent(another_component); ... Automobile auto = (Automobile)yan.getInstance("auto"); And when it comes to the time to initialize and start live components that support these phases, the LifecycleManager object can be used this way: man.init(); man.start(); More than one livesBecause LifecycleManager is independent of Container, it is possible that components from different containers are managed by the same LifecycleManager object. It is also possible that the same component is managed by two different LifecycleManager objects, so that using different LifecycleManager object, we get different treatment of lifecycle for the same component. DefaultLifecycleManager man1 = new DefaultLifecycleManager(); DefaultLifecycleManager man2 = new DefaultLifecycleManager(); Component c = ...; c = man1.newLifecycle() .starter("start1") .stopper("stop1") .manage(c); c = man2.newLifecycle() .starter("start2") .stopper("stop2") .manage(c); ... container.registerComponent("key", c); ... container.getInstance("key"); ... Then, we can use the object man1 to invoke the "start1" and "stop1" methods. We can also use object man2 to invoke the "start2" and "stop2" methods. man1.start(); //start1() is called. man2.start(); //start2() is called. man2.stop(); //stop2() is called. man1.stop(); //stop1() is called. Advanced LifecycleThe DefaultLifecycleManager is designed to make it handy for the several frequently used life cycle phases. If you want more sophisticated life-cycle, you can always use the LifecycleManager class directly for finer control. For example, class PooledThread has such requirement:
The DefaultLifecycleManager is not useful in this case, we use LifecycleManager directly: LifecycleManager man = new LifecycleManager(); Lifecycle life = new Lifecycle(); life.put("stopper", new Procedure(){ void invoke(Object self, Object[] args){ PooledThread target = (PooledThread)self; Boolean force = (Boolean)args[0]; System.out.println("closiing thead..."); target.stop(force.booleanValue()); } }, true); Component pooled_thread = ...; Component live_thread = man.withLifecycle(pooled_thread, life);
The registration and instantiation of live_thread is exactly the same as we showed before. Finally when we need to invoke the "stop" phase, we do: man.filo( "stopper", new Object[]{Boolean.valueOf(true)}, ExceptionHandlers.suppresser() );
Similarly, we can run a non-force stop with exceptions printed out: man.filo( "closer", new Object[]{Boolean.valueOf(false)}, ExceptionHandlers.printer() ); Created by benyu |
|||||
|
Copyright 2003-2006 - The Codehaus. All rights reserved unless otherwise noted.
Powered by Atlassian Confluence
|
|||||