diff --git a/context/src/main/java/io/micronaut/runtime/Micronaut.java b/context/src/main/java/io/micronaut/runtime/Micronaut.java index ae3b6415a1e..3b270a3dd6e 100644 --- a/context/src/main/java/io/micronaut/runtime/Micronaut.java +++ b/context/src/main/java/io/micronaut/runtime/Micronaut.java @@ -18,6 +18,7 @@ import io.micronaut.context.ApplicationContext; import io.micronaut.context.ApplicationContextBuilder; import io.micronaut.context.DefaultApplicationContextBuilder; +import io.micronaut.context.RuntimeBeanDefinition; import io.micronaut.context.banner.Banner; import io.micronaut.context.banner.MicronautBanner; import io.micronaut.context.banner.ResourceBanner; @@ -220,6 +221,11 @@ private static long elapsedMillis(long startNanos) { return (Micronaut) super.singletons(beans); } + @Override + public Micronaut beanDefinitions(@NonNull RuntimeBeanDefinition... definitions) { + return (Micronaut) super.beanDefinitions(definitions); + } + @Override public @NonNull Micronaut propertySources(@Nullable PropertySource... propertySources) { return (Micronaut) super.propertySources(propertySources); diff --git a/inject-java/src/test/groovy/io/micronaut/inject/beans/RuntimeBeanDefinitionSpec.groovy b/inject-java/src/test/groovy/io/micronaut/inject/beans/RuntimeBeanDefinitionSpec.groovy index 0d1090eeb93..44d48898496 100644 --- a/inject-java/src/test/groovy/io/micronaut/inject/beans/RuntimeBeanDefinitionSpec.groovy +++ b/inject-java/src/test/groovy/io/micronaut/inject/beans/RuntimeBeanDefinitionSpec.groovy @@ -17,6 +17,19 @@ class RuntimeBeanDefinitionSpec extends AbstractTypeElementSpec { @Shared BeanContext sharedContext = BeanContext.build() + void "test runtime bean definition registered with builder"() { + given: + def foo = new Foo() + def context = ApplicationContext.builder() + .beanDefinitions(RuntimeBeanDefinition.of(foo)) + .build() + .start() + + expect: + context.getBeanDefinition(Foo) + context.getBean(Foo).is(foo) + } + void 'test simple runtime bean definition'() { given: diff --git a/inject/src/main/java/io/micronaut/context/ApplicationContextBuilder.java b/inject/src/main/java/io/micronaut/context/ApplicationContextBuilder.java index 5d95dbd4568..c661cf89a18 100644 --- a/inject/src/main/java/io/micronaut/context/ApplicationContextBuilder.java +++ b/inject/src/main/java/io/micronaut/context/ApplicationContextBuilder.java @@ -96,6 +96,16 @@ public interface ApplicationContextBuilder { */ @NonNull ApplicationContextBuilder singletons(@Nullable Object... beans); + /** + * Register additional runtime bean definitions prior to startup. + * @param definitions The definitions. + * @return The context builder + * @since 4.5.0 + */ + default @NonNull ApplicationContextBuilder beanDefinitions(@NonNull RuntimeBeanDefinition... definitions) { + return this; + }; + /** * If set to {@code true} (the default is {@code true}) Micronaut will attempt to automatically deduce the environment * it is running in using environment variables and/or stack trace inspection. diff --git a/inject/src/main/java/io/micronaut/context/DefaultApplicationContextBuilder.java b/inject/src/main/java/io/micronaut/context/DefaultApplicationContextBuilder.java index 41c9999cb45..84e204cf1a7 100644 --- a/inject/src/main/java/io/micronaut/context/DefaultApplicationContextBuilder.java +++ b/inject/src/main/java/io/micronaut/context/DefaultApplicationContextBuilder.java @@ -49,6 +49,7 @@ */ public class DefaultApplicationContextBuilder implements ApplicationContextBuilder, ApplicationContextConfiguration { private final List singletons = new ArrayList<>(); + private final List> beanDefinitions = new ArrayList<>(); private final List environments = new ArrayList<>(); private final List defaultEnvironments = new ArrayList<>(); private final List packages = new ArrayList<>(); @@ -153,6 +154,14 @@ public Set> getEagerInitAnnotated() { return this; } + @Override + public ApplicationContextBuilder beanDefinitions(@NonNull RuntimeBeanDefinition... definitions) { + if (definitions != null) { + beanDefinitions.addAll(Arrays.asList(definitions)); + } + return this; + } + @Override public @NonNull ClassPathResourceLoader getResourceLoader() { if (classPathResourceLoader == null) { @@ -346,6 +355,12 @@ public boolean isEnvironmentPropertySource() { } } + if (!beanDefinitions.isEmpty()) { + for (RuntimeBeanDefinition beanDefinition : beanDefinitions) { + applicationContext.registerBeanDefinition(beanDefinition); + } + } + if (!configurationIncludes.isEmpty()) { environment.addConfigurationIncludes(configurationIncludes.toArray(StringUtils.EMPTY_STRING_ARRAY)); }