io.micronaut.context.ApplicationContext Maven / Gradle / Ivy
/*
* Copyright 2017-2020 original authors
*
* Licensed 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
*
* https://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.
*/
package io.micronaut.context;
import io.micronaut.context.env.Environment;
import io.micronaut.context.env.PropertyPlaceholderResolver;
import io.micronaut.context.env.PropertySource;
import io.micronaut.context.env.SystemPropertiesPropertySource;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.util.ArgumentUtils;
import io.micronaut.core.util.StringUtils;
import io.micronaut.core.value.PropertyResolver;
import java.util.Collections;
import java.util.Map;
import java.util.function.Consumer;
/**
* An application context extends a {@link BeanContext} and adds the concepts of configuration, environments and
* runtimes.
*
* The {@link ApplicationContext} is the main entry point for starting and running Micronaut applications. It
* can be thought of as a container object for all dependency injected objects.
*
* The {@link ApplicationContext} can be started via the {@link #run()} method. For example:
*
*
* ApplicationContext context = ApplicationContext.run();
*
*
* Alternatively, the {@link #builder()} method can be used to customize the {@code ApplicationContext} using the {@link ApplicationContextBuilder} interface
* prior to running. For example:
*
* ApplicationContext context = ApplicationContext.builder().environments("test").start();
*
*
* The {@link #getEnvironment()} method can be used to obtain a reference to the application {@link Environment}, which contains the loaded configuration
* and active environment names.
*
* @see ApplicationContextBuilder
* @see Environment
* @author Graeme Rocher
* @since 1.0
*/
public interface ApplicationContext extends BeanContext, PropertyResolver, PropertyPlaceholderResolver {
/**
* @return The application environment
*/
@NonNull Environment getEnvironment();
/**
* Starts the application context.
*
* @return The application context
*/
@Override
@NonNull ApplicationContext start();
/**
* Stops the application context.
*
* @return The application context
*/
@Override
@NonNull ApplicationContext stop();
@Override
@NonNull ApplicationContext registerSingleton(@NonNull Class type, @NonNull T singleton, @Nullable Qualifier qualifier, boolean inject);
@Override
default @NonNull ApplicationContext registerSingleton(@NonNull Class type, @NonNull T singleton, @Nullable Qualifier qualifier) {
return registerSingleton(type, singleton, qualifier, true);
}
@Override
default @NonNull ApplicationContext registerSingleton(@NonNull Class type, @NonNull T singleton) {
return registerSingleton(type, singleton, null, true);
}
@Override
default @NonNull ApplicationContext registerSingleton(@NonNull Object singleton, boolean inject) {
return (ApplicationContext) BeanContext.super.registerSingleton(singleton, inject);
}
/**
* Allow configuration the {@link Environment}.
*
* @param consumer The consumer
* @return This context
*/
default @NonNull ApplicationContext environment(@NonNull Consumer consumer) {
ArgumentUtils.requireNonNull("consumer", consumer);
consumer.accept(getEnvironment());
return this;
}
@Override
default @NonNull ApplicationContext registerSingleton(@NonNull Object singleton) {
ArgumentUtils.requireNonNull("singleton", singleton);
Class type = singleton.getClass();
return registerSingleton(type, singleton);
}
/**
* Run the {@link ApplicationContext}. This method will instantiate a new {@link ApplicationContext} and
* call {@link #start()}.
*
* @param environments The environments to use
* @return The running {@link ApplicationContext}
*/
static @NonNull ApplicationContext run(@NonNull String... environments) {
ArgumentUtils.requireNonNull("environments", environments);
return builder(environments).start();
}
/**
* Run the {@link ApplicationContext}. This method will instantiate a new {@link ApplicationContext} and
* call {@link #start()}.
*
* @return The running {@link ApplicationContext}
*/
static @NonNull ApplicationContext run() {
return run(StringUtils.EMPTY_STRING_ARRAY);
}
/**
* Run the {@link ApplicationContext} with the given type. Returning an instance of the type. Note this method
* should not be used.
* If the {@link ApplicationContext} requires graceful shutdown unless the returned bean takes responsibility for
* shutting down the context.
*
* @param properties Additional properties
* @param environments The environment names
* @return The running {@link ApplicationContext}
*/
static @NonNull ApplicationContext run(@NonNull Map properties, @NonNull String... environments) {
ArgumentUtils.requireNonNull("environments", environments);
ArgumentUtils.requireNonNull("properties", properties);
PropertySource propertySource = PropertySource.of(PropertySource.CONTEXT, properties, SystemPropertiesPropertySource.POSITION + 100);
return run(propertySource, environments);
}
/**
* Run the {@link ApplicationContext} with the given type. Returning an instance of the type. Note this method
* should not be used.
* If the {@link ApplicationContext} requires graceful shutdown unless the returned bean takes responsibility for
* shutting down the context.
*
* @param properties Additional properties
* @param environments The environment names
* @return The running {@link ApplicationContext}
*/
static @NonNull ApplicationContext run(@NonNull PropertySource properties, @NonNull String... environments) {
ArgumentUtils.requireNonNull("environments", environments);
ArgumentUtils.requireNonNull("properties", properties);
return builder(environments)
.propertySources(properties)
.start();
}
/**
* Run the {@link ApplicationContext} with the given type. Returning an instance of the type. Note this method
* should not be used.
* If the {@link ApplicationContext} requires graceful shutdown unless the returned bean takes responsibility for
* shutting down the context.
*
* @param type The type of the bean to run
* @param environments The environments to use
* @param The type
* @return The running bean
*/
static @NonNull T run(@NonNull Class type, @NonNull String... environments) {
ArgumentUtils.requireNonNull("type", type);
ArgumentUtils.requireNonNull("environments", environments);
return run(type, Collections.emptyMap(), environments);
}
/**
* Run the {@link ApplicationContext} with the given type. Returning an instance of the type. Note this method
* should not be used.
* If the {@link ApplicationContext} requires graceful shutdown unless the returned bean takes responsibility for
* shutting down the context.
*
* @param type The type of the bean to run
* @param properties Additional properties
* @param environments The environment names
* @param The type
* @return The running bean
*/
static @NonNull T run(@NonNull Class type, @NonNull Map properties, @NonNull String... environments) {
ArgumentUtils.requireNonNull("environments", environments);
ArgumentUtils.requireNonNull("properties", properties);
ArgumentUtils.requireNonNull("type", type);
PropertySource propertySource = PropertySource.of(PropertySource.CONTEXT, properties, SystemPropertiesPropertySource.POSITION + 100);
return run(type, propertySource, environments);
}
/**
* Run the {@link ApplicationContext} with the given type. Returning an instance of the type. Note this method
* should not be used.
* If the {@link ApplicationContext} requires graceful shutdown unless the returned bean takes responsibility for
* shutting down the context.
*
* @param type The environment to use
* @param propertySource Additional properties
* @param environments The environment names
* @param The type
* @return The running {@link BeanContext}
*/
static @NonNull T run(@NonNull Class type, @NonNull PropertySource propertySource, @NonNull String... environments) {
ArgumentUtils.requireNonNull("propertySource", propertySource);
ArgumentUtils.requireNonNull("environments", environments);
ArgumentUtils.requireNonNull("type", type);
T bean = builder(environments)
.mainClass(type)
.propertySources(propertySource)
.start()
.getBean(type);
if (bean instanceof LifeCycle lifeCycle) {
if (!lifeCycle.isRunning()) {
lifeCycle.start();
}
}
return bean;
}
/**
* Build a {@link ApplicationContext}.
*
* @param environments The environments to use
* @return The application context builder
*/
static @NonNull ApplicationContextBuilder builder(@NonNull String... environments) {
ArgumentUtils.requireNonNull("environments", environments);
return builder()
.environments(environments);
}
/**
* Build a {@link ApplicationContext}.
*
* @param properties The properties
* @param environments The environments to use
* @return The application context builder
*/
static @NonNull ApplicationContextBuilder builder(@NonNull Map properties, @NonNull String... environments) {
ArgumentUtils.requireNonNull("environments", environments);
ArgumentUtils.requireNonNull("properties", properties);
return builder()
.properties(properties)
.environments(environments);
}
/**
* Build a {@link ApplicationContext}.
*
* @return The application context builder
*/
static @NonNull ApplicationContextBuilder builder() {
return new DefaultApplicationContextBuilder();
}
/**
* @param classLoader The class loader to use
* @return The application context builder
*/
static @NonNull ApplicationContextBuilder builder(ClassLoader classLoader) {
return new DefaultApplicationContextBuilder(classLoader);
}
/**
* Run the {@link BeanContext}. This method will instantiate a new {@link BeanContext} and call {@link #start()}
*
* @param classLoader The classloader to use
* @param environments The environments to use
* @return The running {@link ApplicationContext}
*/
static @NonNull ApplicationContext run(@NonNull ClassLoader classLoader, @NonNull String... environments) {
ArgumentUtils.requireNonNull("environments", environments);
ArgumentUtils.requireNonNull("classLoader", classLoader);
return builder(classLoader, environments).start();
}
/**
* Build a {@link ApplicationContext}.
*
* @param classLoader The classloader to use
* @param environments The environment to use
* @return The application context builder
*/
static @NonNull ApplicationContextBuilder builder(@NonNull ClassLoader classLoader, @NonNull String... environments) {
ArgumentUtils.requireNonNull("environments", environments);
ArgumentUtils.requireNonNull("classLoader", classLoader);
return builder(classLoader)
.environments(environments);
}
/**
* Build a {@link ApplicationContext}.
*
* @param mainClass The main class of the application
* @param environments The environment to use
* @return The application context builder
*/
static @NonNull ApplicationContextBuilder builder(@NonNull Class> mainClass, @NonNull String... environments) {
ArgumentUtils.requireNonNull("environments", environments);
ArgumentUtils.requireNonNull("mainClass", mainClass);
return builder(environments)
.mainClass(mainClass);
}
}