You typically need to perform custom actions when the application starts and clean up everything when the application stops.
The main method
By default, Quarkus will automatically generate a main method that will boot Quarkus and then just wait for it to start up and shut down. You need to create your own main method
`package om.acme; ` `import io.quarkus.runtime.annotations.QuarkusMain; ` `import io.quarkus.runtime.Quarkus; ` `@QuarkusMain` `public class Main {` `public static void main(String ... args) {` `System.out.println("Running main method"); ` `Quarkus.run(args); ` ` `} ` `}Copy the code
- This comment tells Quarkus to use this method as the primary method unless it is overridden in the configuration
- Start Quarkus from here
This main class will bootstrap Quarkus and run it until it stops. This is no different from the auto-generated main class, but has the advantage of being able to launch it directly from the IDE without running Maven or Gradle commands.
It is not recommended to execute any business logic in this primary method because Quarkus has not been set up and Quarkus can run in other Classloaders. If you want to perform at startup logic, please use, IO. Quarkus. Runtime. QuarkusApplication as described below.
If you want to actually perform at startup business logic (or write to complete the task and then exit the application), you need to IO quarkus. Runtime. QuarkusApplicationrun method provides a class. Run, after Quarkus is started, calls the application’s methods. When this method returns, the Quarkus application exits.
If logic is to be executed at startup, call quarkus.waitForexit (), which waits until the request is closed (from an external signal (such as Ctrl+C on time or because the thread has called quarkus.asyncexit ())).
`package com.acme; ` `import io.quarkus.runtime.Quarkus; ` `import io.quarkus.runtime.QuarkusApplication; ` `import io.quarkus.runtime.annotations.QuarkusMain; ` `@QuarkusMain` `public class Main {` `public static void main(String... args) {` `Quarkus.run(MyApp.class, args); ` `}` `public static class MyApp implements QuarkusApplication {` `@Override` `public int run(String... args) throws Exception {` `System.out.println("Do startup logic here"); ` `Quarkus.waitForExit(); ` `return 0; ` `} ` `} ` ` `}Copy the code
Inject command line arguments
Arguments that can be injected on the command line:
`@Inject` `@CommandLineArguments` `String[] args; `Copy the code
Listen for startup and shutdown events
Create the AppLifecycleBean class (or use another name) in the org.acme.lifecycle package and copy the following:
`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) {` `LOGGER.info("The application is starting..." ); ` `}` `void onStop(@Observes ShutdownEvent ev) {` `LOGGER.info("The application is stopping..." ); ` ` `} ` `}Copy the code
- Method called when the application starts
- Method called when the application terminates
These events are also called every time dev Mode is redeployed.
These methods can inject beans. see the applifecyclebean.java class for details
What is the difference between @initialized (ApplicationScoped. Class) and @destroyed (ApplicationScoped. Class)
In JVM mode, there’s no real difference, ShutdownEvent is always triggered after @Initialized(ApplicationScoped. Class) and before @Destroyed(ApplicationScoped. Class).
However, when building as a native executable, @Initialized(ApplicationScoped. Class) is fired during the native build process, and StartupEvent is fired during the native image execution. For details, please refer to the three phases of the startup and Quarkus concept.
In CDI applications, an event annotated @Initialized(ApplicationScoped. Class) is triggered when the CDI container is Initialized.
Initialize a CDI bean at program Startup with @startup
The producer method or Bean@Startup represented by an annotated field is initialized when the application starts:
`package org.acme.lifecycle; ` `import javax.enterprise.context.ApplicationScoped; ` `@Startup` `@ApplicationScoped` `public class EagerAppBean {` `private final String name; ` `EagerAppBean(NameGenerator generator) {` `this.name = generator.createName(); ` ` `} ` `}Copy the code
- StartupEvent listeners are synthesized automatically for each bean annotated with @startup. Use the default priority.
- When the program starts, it calls the bean’s constructor and saves the bean to the application context.
Listen beans of type @dependent are destroyed immediately after execution.
If the class annotates @startup but does not annotate the scope is automatically set to @ApplicationScoped.
Package and run the application
Run the./ MVNW compile quarkus:dev command to generate logs. When the application stops, the second log is generated.
In general, applications can be packaged with a./ MVNW clean package and run with a -runner. Jar file. Native executables can also be generated with./ MVNW Clean package-pnative.
The operation mode
Quarkus has three different startup modes: NORMAL (production) DEVELOPMENT and TEST. If running, quarkus:dev is in DEVELOPMENT mode; If JUnit tests are running, the mode is TEST, otherwise NORMAL.
. Your application can use the IO quarkus. Runtime. The LaunchMode enumeration injection CDI beans or call the static method to obtain startup mode. IO quarkus. Runtime. LaunchMode. The current ().
Graceful closure
Quarkus supports smooth shutdown, which allows Quarkus to wait for run requests to complete until a set timeout period. It is disabled by default, but you can configure it by setting the quarkus.shutdown.timeout config property. When this option is set, shutdown does not occur until all running requests have completed or until the timeout period expires. This configuration property is a Duration that can be set using the standard java.time.Duration format, or interpreted as seconds if only a number is specified.
The extension that accepts the request needs to add support for this separately. Currently only the HTTP extension supports this feature, so a shutdown can still occur while a mail request is active.