////
This guide is maintained in the main Quarkus repository
and pull requests should be submitted there:
https://github.com/quarkusio/quarkus/tree/master/docs/src/main/asciidoc
////
= Quarkus - Application Initialization and Termination

include::./attributes.adoc[]

You often need to execute custom actions when the application starts and clean up everything when the application stops.
This guide explains how to:

* be notified when the application starts
* be notified when the application stops

== Prerequisites

To complete this guide, you need:

* less than 10 minutes
* an IDE
* JDK 1.8+ installed with `JAVA_HOME` configured appropriately
* Apache Maven {maven-version}



== Solution

We recommend that you follow the instructions in the next sections and create the application step by step.
However, you can go right to the completed example.

Clone the Git repository: `git clone {quickstarts-clone-url}`, or download an {quickstarts-archive-url}[archive].

The solution is located in the `lifecycle-quickstart` {quickstarts-tree-url}/lifecycle-quickstart[directory].

== Creating the Maven project

First, we need a new project. Create a new project with the following command:

[source,shell,subs=attributes+]
----
mvn io.quarkus:quarkus-maven-plugin:{quarkus-version}:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=lifecycle-quickstart \
    -DclassName="org.acme.lifecycle.GreetingResource" \
    -Dpath="/hello"
cd lifecycle-quickstart
----

It generates:

* the Maven structure
* a landing page accessible on `http://localhost:8080`
* example `Dockerfile` files for both `native` and `jvm` modes
* the application configuration file
* an `org.acme.lifecycle.GreetingResource` resource
* an associated test

== Listening for startup and shutdown events

Create a new class named `AppLifecycleBean` (or pick another name) in the `org.acme.lifecycle` package, and copy the
following content:

[source,java]
----
package org.acme.lifecycle;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;

import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;
import org.jboss.logging.Logger;

@ApplicationScoped
public class AppLifecycleBean {

    private static final Logger LOGGER = Logger.getLogger("ListenerBean");

    void onStart(@Observes StartupEvent ev) {               // <1>
        LOGGER.info("The application is starting...");
    }

    void onStop(@Observes ShutdownEvent ev) {               // <2>
        LOGGER.info("The application is stopping...");
    }

}
----
1. Method called when the application is starting
2. Method called when the application is terminating

TIP: The events are also called in _dev mode_ between each redeployment.

NOTE: The methods can access injected beans. Check the {quickstarts-blob-url}/lifecycle-quickstart/src/main/java/org/acme/lifecycle/AppLifecycleBean.java[AppLifecycleBean.java] class for details.

=== What is the difference from `@Initialized(ApplicationScoped.class)` and `@Destroyed(ApplicationScoped.class)`

In the JVM mode, there is no real difference, except that `StartupEvent` is always fired *after* `@Initialized(ApplicationScoped.class)` and `ShutdownEvent` is fired *before* `@Destroyed(ApplicationScoped.class)`. 
For a native executable build, however, `@Initialized(ApplicationScoped.class)` is fired as *part of the native build process*, whereas `StartupEvent` is fired when the native image is executed.
See link:writing-extensions#bootstrap-three-phases[Three Phases of Bootstrap and Quarkus Philosophy] for more details.

NOTE: In CDI applications, an event with qualifier `@Initialized(ApplicationScoped.class)` is fired when the application context is initialized. See https://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#application_context[the spec, window="_blank"] for more info.

=== Using `@Startup` to initialize a CDI bean at application startup

A bean represented by a class, producer method or field annotated with `@Startup` is initialized at application startup:

[source,java]
----
package org.acme.lifecycle;

import javax.enterprise.context.ApplicationScoped;

@Startup // <1> 
@ApplicationScoped
public class EagerAppBean {
  
   private final String name;

   EagerAppBean(NameGenerator generator) { // <2>
     this.name = generator.createName();
   }
}
----
1. For each bean annotated with `@Startup` a synthetic observer of `StartupEvent` is generated. The default priority is used.
2. The bean constructor is called when the application starts and the resulting contextual instance is stored in the application context.

NOTE: `@Dependent` beans are destroyed immediately afterwards to follow the behavior of observers declared on `@Dependent` beans.

TIP: If a class is annotated with `@Startup` but with no scope annotation then `@ApplicationScoped` is added automatically.

== Package and run the application

Run the application with: `./mvnw compile quarkus:dev`, the logged message is printed.
When the application is stopped, the second log message is printed.

As usual, the application can be packaged using `./mvnw clean package` and executed using the `-runner.jar` file.
You can also generate the native executable using `./mvnw clean package -Pnative`.

== Launch Modes

Quarkus has 3 different launch modes, `NORMAL` (i.e. production), `DEVELOPMENT` and `TEST`. If you are running `quarkus:dev`
then the mode will be `DEVELOPMENT`, if you are running a JUnit test it will be `TEST`, otherwise it will be `NORMAL`.

Your application can get the launch mode by injecting the `io.quarkus.runtime.LaunchMode` enum into a CDI bean,
or by invoking the static method `io.quarkus.runtime.LaunchMode.current()`.

== Graceful Shutdown

Quarkus includes support for graceful shutdown, this allows Quarkus to wait for running requests to finish, up
till a set timeout. By default this is disabled, however you can configure this by setting the `quarkus.shutdown.timeout`
config property. When this is set shutdown will not happen until all running requests have completed, or until
this timeout has elapsed. This config property is a duration, and can be set using the standard
`java.time.Duration` format, if only a number is specified it is interpreted as seconds.

Extensions that accept requests need to add support for this on an individual basis. At the moment only the
HTTP extension supports this, so shutdown may still happen when messaging requests are active.