A brief talk on Java lifecycle Management mechanism _java

Source: Internet
Author: User
Tags getmessage throwable

Let's talk.

Recently has been studying a domestic open source of MySQL database middleware, pull down the latest version of the code to eclipse, start up, and then do a variety of tests and code tracking, when you want to close it, pull out the stop class when you want to run, found that the class is impressively only write the following lines of code, So I feel a lot of hurt in a moment.

  public static void Main (string[] args) {
    System.out.println (new Date () + ", Server shutdown!");
  }

When the middleware starts and runs, it turns on listening, starts a lot of threads running, and has many socket connections. But did not find an elegant way to turn it off. So helpless, I can only go to the eclipse of the heart Little Red dot, forcibly stop the VM.

It is important to have a lifecycle management mechanism for a well structured, modular software, especially for server class software. Not only can you manage the lifecycle of each module, but you can also be more elegant when you start and stop the entire software, without omitting any resources.

Simple realization of life cycle mechanism

Life cycle State

The life cycle state of a module generally has several following:

-> initialization completed in newborn-> initialization-> start-> boot complete-> is paused-> has been paused-> is resuming-> has been restored-> is being destroyed-> has been destroyed
In which, if the transformation between any one State fails, it will enter another state: failure.

To do this, you can use an enumeration class to enumerate these states, as follows:

public enum Lifecyclestate {

  new,//new

  initializing, initialized,//Initialize

  starting, started,/start

  Suspending, suspended,//pause

  resuming, resumed,//restore

  destroying, destroyed,//destroy

  failed;//failed

}

Interface

The various behavioral specifications in the lifecycle also require an interface to define, as follows:

 public interface Ilifecycle {/** * initialization * * @throws lifecycleexception *

  /public void Init () throws lifecycleexception;

  /** * Start * * @throws lifecycleexception/public void Start () throws lifecycleexception;

  /** * Suspend * @throws lifecycleexception/public void suspend () throws lifecycleexception;

  /** * Restore * * @throws lifecycleexception/public void Resume () throws lifecycleexception;

  /** * Destroy * * @throws lifecycleexception/public void Destroy () throws lifecycleexception;

  /** * Add life cycle listener * * @param listener */public void Addlifecyclelistener (Ilifecyclelistener listener);

/** * Delete life cycle listener * * @param listener/public void Removelifecyclelistener (Ilifecyclelistener listener); }

When a lifecycle state transformation occurs, it may be necessary to trigger listeners interested in certain types of events, so ilifecycle also defines two methods to add and remove listeners. are: public void Addlifecyclelistener (Ilifecyclelistener listener), and public void Removelifecyclelistener ( Ilifecyclelistener listener);

The listener also defines its behavior specification by an interface, as follows:

Public interface Ilifecyclelistener {

  /**
   * Handling Lifecycle Events
   * 
   @param event Lifecycle Event
  /public void Lifecycleevent (Lifecycleevent event);
}

Life cycle events are represented by Lifecycleevent, as follows:

Public final class Lifecycleevent {

  private lifecyclestate state;

  Public lifecycleevent (lifecyclestate state) {
    this.state = state;
  }

  /** * @return The state * *
   /public
  lifecyclestate getState () {return state
    ;
  }

}

Skeleton implementation

With the Ilifecycle interface, any class that implements this interface will be treated as a lifecycle management object, which can be a socket listening service, a specific module, and so on. So, do we just have to realize ilifecycle? You can say that, but consider that each lifecycle management object has some common behavior at various stages of the lifecycle, such as:

Set the life cycle state of itself
Check if the transition of the state is logical
Notifies the listener that the life cycle state has changed
Therefore, it is important to provide an abstract class abstractlifecycle as a skeleton implementation of ilifecycle, thus avoiding a lot of duplicate code and making the architecture clearer. This abstract class implements all of the interface methods defined in Ilifecycle and adds corresponding abstract methods for subclasses to implement. Abstractlifecycle can be implemented like this:

Public abstract class Abstractlifecycle implements Ilifecycle {private list<ilifecyclelistener> listeners = new

  Copyonwritearraylist<ilifecyclelistener> ();

  /** * State represents the current life cycle status */private lifecyclestate states = Lifecyclestate.new; * * @see ilifecycle#init () * * * @Override public final synchronized void Init () throws Lifecycleexception {I
    F (State!= lifecyclestate.new) {return;
    } setstateandfireevent (lifecyclestate.initializing);
    try {init0 ();
      catch (Throwable t) {setstateandfireevent (lifecyclestate.failed);
      if (t instanceof lifecycleexception) {throw (lifecycleexception) t; else {throw new Lifecycleexception (formatstring ("Failed to initialize {0}, Error Msg: {1}", Tostri
      Ng (), T.getmessage ()), T);
  } setstateandfireevent (lifecyclestate.initialized);

  protected abstract void Init0 () throws lifecycleexception; * * @see ilifecycle#sTart () */@Override public final synchronized void start () throws Lifecycleexception {if (state = = Lifecyclest Ate.
    NEW) {init ();
    } if (state!= lifecyclestate.initialized) {return;
    } setstateandfireevent (lifecyclestate.starting);
    try {start0 ();
      catch (Throwable t) {setstateandfireevent (lifecyclestate.failed);
      if (t instanceof lifecycleexception) {throw (lifecycleexception) t; else {throw new Lifecycleexception (formatstring ("Failed to start {0}, Error Msg: {1}", ToString (),
      T.getmessage ()), T);
  } setstateandfireevent (lifecyclestate.started);

  protected abstract void Start0 () throws lifecycleexception; 
    * * @see ilifecycle#suspend () * * * @Override public final synchronized void suspend () throws Lifecycleexception {
    if (state = = Lifecyclestate.suspending | | state = = lifecyclestate.suspended) {return; } if (State!= LifecyclestaTe.
    started) {return;
    } setstateandfireevent (lifecyclestate.suspending);
    try {suspend0 ();
      catch (Throwable t) {setstateandfireevent (lifecyclestate.failed);
      if (t instanceof lifecycleexception) {throw (lifecycleexception) t; else {throw new Lifecycleexception (formatstring ("Failed to suspend {0}, Error Msg: {1}", ToString ()
      , T.getmessage ()), T);
  } setstateandfireevent (lifecyclestate.suspended);

  protected abstract void Suspend0 () throws lifecycleexception;
    * * @see Ilifecycle#resume () * * * @Override public final synchronized void resume () throws Lifecycleexception {
    if (state!= lifecyclestate.suspended) {return;
    } setstateandfireevent (lifecyclestate.resuming);
    try {RESUME0 ();
      catch (Throwable t) {setstateandfireevent (lifecyclestate.failed);
      if (t instanceof lifecycleexception) {throw (lifecycleexception) t;else {throw new Lifecycleexception (formatstring ("Failed to resume {0}, Error Msg: {1}", ToString (),
      T.getmessage ()), T);
  } setstateandfireevent (lifecyclestate.resumed);

  protected abstract void Resume0 () throws lifecycleexception; 
    * * @see Ilifecycle#destroy () * * * @Override public final synchronized void Destroy () throws Lifecycleexception {
    if (state = = Lifecyclestate.destroying | | state = = lifecyclestate.destroyed) {return;
    } setstateandfireevent (lifecyclestate.destroying);
    try {destroy0 ();
      catch (Throwable t) {setstateandfireevent (lifecyclestate.failed);
      if (t instanceof lifecycleexception) {throw (lifecycleexception) t; else {throw new Lifecycleexception (formatstring ("Failed to destroy {0}, Error Msg: {1}", ToString ()
      , T.getmessage ()), T);
  } setstateandfireevent (lifecyclestate.destroyed); } protected abstract void desTroy0 () throws lifecycleexception; * * * @see * Ilifecycle#addlifecyclelistener (ilifecyclelistener)/@Override public void Addlifecyclelistener (Ilifecyclelistener Listener)
  {Listeners.add (listener); }/* * @see * Ilifecycle#removelifecyclelistener (ilifecyclelistener)/@Override public void Removelifecy
  Clelistener (Ilifecyclelistener listener) {listeners.remove (listener); } private void Firelifecycleevent (Lifecycleevent event) {for (iterator<ilifecyclelistener> it = listeners.it Erator (); It.hasnext ();)
      {Ilifecyclelistener listener = It.next ();
    Listener.lifecycleevent (event);
  } protected synchronized Lifecyclestate getState () {return state; Private synchronized void Setstateandfireevent (Lifecyclestate newstate) throws lifecycleexception {state = Newst
    Ate
  Firelifecycleevent (New Lifecycleevent (state)); private string formatstring (string pattern, Object ... arguments) {RetuRN Messageformat.format (pattern, arguments); /* * @see java.lang.object#tostring () */@Override public String toString () {return getclass (). Getsimp
  Lename ();

 }
}

As you can see, the skeleton implementations of the abstract class do a few things that are common in life cycle management, checking whether transitions between states are legitimate (such as having to init before start), setting the internal state, and triggering the corresponding listener.

The abstract class implements the method defined by Ilifecycle and leaves the corresponding abstract method for its subclass implementation, as shown in the preceding code, which has the following abstract methods:

protected abstract void Init0 () throws lifecycleexception;
protected abstract void Start0 () throws lifecycleexception;
protected abstract void Suspend0 () throws lifecycleexception;
protected abstract void Resume0 () throws lifecycleexception;
protected abstract void Destroy0 () throws lifecycleexception;

Elegance of implementation

So far, we have defined the interface ilifecycle, and its skeleton implementation abstractlifecycle, and has increased the listener mechanism. It looks like we can start writing a class to inherit abstractlifecycle and rewrite the abstract method that it defines, so good of so far.

But before we begin, we need to consider a few other questions,

Are our implementation classes interested in all of the abstract methods?
Is every implementation tiring required to achieve init0, start0, Suspend0, RESUME0, destroy0?
Are there times when our life-like classes or modules do not support pauses (suspend), restores (resume)?
Direct inheritance of abstractlifecycle means that all of its abstract methods must be implemented.
So we also need a default implementation, Defaultlifecycle, let it inherit abstractlifecycle, and implement all the abstract methods, but it doesn't do anything practical, doing nothing. Just let our real implementation class inherit this default implementation class and rewrite the methods of interest.

So, our defaultlifecycle was born:

public class Defaultlifecycle extends Abstractlifecycle {
   * * * @see abstractlifecycle#init0 () * *
  Override
  protected void Init0 () throws Lifecycleexception {
    //Do nothing
  }

  /
   * @see Abstractlifecycle#start0 ()
   */
  @Override
  protected void start0 () throws Lifecycleexception {
    // Do nothing
  }
   /* @see abstractlifecycle#suspend0 () * * * *
  @Override
  protected void Suspendinternal () throws Lifecycleexception {
    //Do nothing
  }
   * * @see ABSTRACTLIFECYCLE#RESUME0 ()
   *
  /@Override protected void Resume0 () throws Lifecycleexception {
    //Do nothing}/

  *
   * @see abstractlifecycle#destroy0 () * * *
  @Override
  protected void destroy0 () throws lifecycleexception {
    //Do Nothing
  }

}

For Defaultlifecycle, doing nothing is his duty.
So then we can write our own implementation class, inherit defaultlifecycle, and rewrite those interesting lifecycle methods.

For example, I have a class that only needs to do some tasks when initializing, starting, and destroying, so you can write:

Import java.io.IOException;
Import Java.net.ServerSocket;

Import Java.net.Socket;
  public class Socketserver extends Defaultlifecycle {private ServerSocket acceptor = null;
  private int port = 9527;
      /* * @see defaultlifecycle#init0 () * * * @Override protected void init0 () throws Lifecycleexception {try {
    Acceptor = new ServerSocket (port);
    catch (IOException e) {throw new Lifecycleexception (e);
    }/* * @see defaultlifecycle#start0 () * * * @Override protected void start0 () throws Lifecycleexception {
    Socket socket = NULL;
      try {socket = acceptor.accept ();
    Do something with socket} catch (IOException e) {throw new Lifecycleexception (e);
        finally {if (socket!= null) {try {socket.close ();
        catch (IOException e) {//TODO auto-generated catch block E.printstacktrace (); }}}/* * @see DefaultlifecyCLE#DESTROY0 () */@Override protected void Destroy0 () throws Lifecycleexception {if (acceptor!= null) {
      try {acceptor.close ();
      catch (IOException e) {//TODO auto-generated catch block E.printstacktrace ();

 }
    }
  }
}

Here in the ServerSocket, INIT0 initialization socket listening, START0 began to obtain socket connection, DESTROY0 destroy socket monitoring.
Under this lifecycle management mechanism, we will be able to easily manage the resources without the resources being shut down, and the architecture and modularity become clearer.

End

So far, this article has implemented a simple lifecycle management mechanism, and given all the implementation code. All the source code is then placed on the GitHub. Please pay attention to the update in this article.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.