When Nucleus creates a component from a properties file, it goes through the following steps:
Nucleus constructs the component using the public constructor with no arguments.
Nucleus binds the component into its parent
NameContext
.If the
NameContext
implementsNameContextBindingEventSource
and the component implementsNameContextBindingListener
, the component is notified that it was bound into aNameContext
.Nucleus then configures the component by setting its properties from the values found in the properties configuration file. This might involve resolving names of other components, which can involve creating, binding, and configuring those components as well.
Nucleus then adds any event listeners defined in the properties file. Again, this involves resolving component names by finding or creating those components.
After all of the component’s properties are set and its event listeners added, the component is ready to go. Nucleus now notifies the component that it is all set up and ready to start. This notification is only performed if the component implements
atg.nucleus.ServiceListener
.
Notice how the component can receive two notifications—one when it is bound into the NameContext
, and one when Nucleus is finished configuring its property values. Most application components wait until the second notification before starting their operations. In order for a component to receive this second notification, it must implement atg.nucleus.ServiceListener
.
The following is a typical implementation of ServiceListener
:
Nucleus nucleus; Configuration configuration; boolean running; public void startService (ServiceEvent ev) throws ServiceException { if (ev.getService () == this && !running) { nucleus = ev.getNucleus (); configuration = ev.getServiceConfiguration (); running = true; doStartService (); } } public void stopService () throws ServiceException { if (running) { running = false; doStopService (); } } public void doStartService () throws ServiceException {} public void doStopService () throws ServiceException {}
First, notice that startService
checks the service specified by the event to make sure that it is actually this service. Second, notice the use of a running
flag. This flag is needed because Nucleus might call startService
multiple times, even after calling startService
a first time. The use of the running
flag makes sure that the service performs its initialization functions only once. In this particular implementation, run-once logic is placed in startService
, while the actual initialization procedures are delegated to another method, such as doStartService
.
A similar technique is used for the stopService
method. The running
flag is used to make sure that the shutdown procedures are executed only once, and the actual shutdown procedures are delegated to the doStopService
method. A service might be stopped for a variety of reasons: a direct command from the administrator, overall Nucleus shutdown, or service reconfiguration.
A service that has been stopped should be prepared to start again at any time. For example, when reconfiguring a service, the administrator typically stops the service, changes some configuration values, then restarts the service. The service is expected to restart itself using the new configuration values. Thus, a service can expect to be stopped and restarted several times during its lifetime in Nucleus.
Both start and stop methods can throw a ServiceException
to indicate that some problem has occurred during startup or shutdown.