<!--
/***************************************************************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *  
 *  http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations under the License.
 ***************************************************************************************************************************/
 -->

Lifecycle Methods

<p>
	To review, the {@link oaj.microservice.Microservice} class contains the following lifecycle methods:
</p>
<ul class='javatree'>
	<li class='jc'>{@link oaj.microservice.Microservice}
	<ul>
		<li class='jm'>{@link oaj.microservice.Microservice#start() start()} 
		<li class='jm'>{@link oaj.microservice.Microservice#startConsole() startConsole()} 
		<li class='jm'>{@link oaj.microservice.Microservice#join() join()} 
		<li class='jm'>{@link oaj.microservice.Microservice#stop() stop()} 
		<li class='jm'>{@link oaj.microservice.Microservice#stopConsole() stopConsole()} 
		<li class='jm'>{@link oaj.microservice.Microservice#exit() exit()} 
		<li class='jm'>{@link oaj.microservice.Microservice#kill() kill()} 
	</ul>
</ul>
<p>
	The {@link oaj.microservice.jetty.JettyMicroservice} class which extends from {@link oaj.microservice.Microservice} 
	provides the following additional lifecycle methods:
</p>
<ul class='javatree'>
	<li class='jc'>{@link oaj.microservice.jetty.JettyMicroservice}
	<ul>
		<li class='jm'>{@link oaj.microservice.jetty.JettyMicroservice#createServer() createServer()} 
		<li class='jm'>{@link oaj.microservice.jetty.JettyMicroservice#startServer() startServer()} 
		<li class='jm'>{@link oaj.microservice.jetty.JettyMicroservice#destroyServer() destroyServer()} 
	</ul>
</ul>
<p>
	The additional lifecycle methods are typically not called directly, but are exposed to allow subclasses to
	provide customized behavior for these events.  
	For this reason, these methods are left as non-final so that they can be overridden.
</p>
<p>
	A typical implementation of an app with lifecycle methods might look like the following:
</p>
<p class='bpcode w800'>
	<jk>public class</jk> App {
	
		<jk>private static final</jk> JettyMicroservice <jsf>MICROSERVICE</jsf>;
	
		<jk>public static void</jk> main(String[] args) {
			<jsf>MICROSERVICE</jsf> = JettyMicroservice
				.<jsm>create</jsm>()                     <jc>// Create builder.</jc>
				.args(args)                   <jc>// Pass in args.</jc>
				.servlets(RootResource.<jk>class</jk>) <jc>// A Juneau RestServlet class.</jc>
				.build()                      <jc>// Create microservice.</jc>
				.start()                      <jc>// Start microservice.</jc>
				.startConsole()               <jc>// Start console.</jc>
				.join()                       <jc>// Join thread.</jc>
			;
		}
		
		<jk>public static void</jk> restart() {
			<jsf>MICROSERVICE</jsf>.stop().start();
		}
		
		<jk>public static void</jk> exit() {
			<jsf>MICROSERVICE</jsf>.exit();
		}
	}
</p>
<p>
	Similar to {@link oaj.microservice.Microservice#getInstance()}, the {@link oaj.microservice.jetty.JettyMicroservice#getInstance()}
	also allows easy access to the microservice:
</p>
<p class='bpcode w800'>
	<jk>public class</jk> App {
	
		<jk>public static void</jk> main(String[] args) {
			JettyMicroservice
				.<jsm>create</jsm>()                     <jc>// Create builder.</jc>
				.args(args)                   <jc>// Pass in args.</jc>
				.servlets(RootResource.<jk>class</jk>) <jc>// A Juneau RestServlet class.</jc>
				.build()                      <jc>// Create microservice.</jc>
				.start()                      <jc>// Start microservice.</jc>
				.startConsole()               <jc>// Start console.</jc>
				.join()                       <jc>// Join thread.</jc>
			;
		}
		
		<jk>public static void</jk> restart() {
			JettyMicroservice.<jsm>getInstance</jsm>().stop().start();
		}
		
		<jk>public static void</jk> exit() {
			JettyMicroservice.<jsm>getInstance</jsm>().exit();
		}
	}
</p>
