diff --git a/platform-plugins/flamingock-springboot-integration/src/main/java/io/flamingock/springboot/FlamingockAutoConfiguration.java b/platform-plugins/flamingock-springboot-integration/src/main/java/io/flamingock/springboot/FlamingockAutoConfiguration.java
index cca6d3d14..cb375bb40 100644
--- a/platform-plugins/flamingock-springboot-integration/src/main/java/io/flamingock/springboot/FlamingockAutoConfiguration.java
+++ b/platform-plugins/flamingock-springboot-integration/src/main/java/io/flamingock/springboot/FlamingockAutoConfiguration.java
@@ -24,11 +24,13 @@
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
import java.util.List;
@@ -37,11 +39,14 @@
*
*
The configuration behavior is controlled by the {@code flamingock.management-mode} property:
*
- * - {@code APPLICATION_RUNNER} (default) - Spring creates, builds, and executes the runner as an ApplicationRunner
- * - {@code INITIALIZING_BEAN} - Spring creates, builds, and executes the runner as an InitializingBean
+ * - {@code APPLICATION_RUNNER} (default) - Spring creates the builder and executes it as an ApplicationRunner
+ * - {@code INITIALIZING_BEAN} - Spring creates the builder and executes it as an InitializingBean
* - {@code DEFERRED} - Spring creates the builder; the application controls execution
* - {@code UNMANAGED} - No beans are created; the application manages everything
*
+ *
+ * The builder bean is always created (unless UNMANAGED) and can be overridden by providing
+ * your own {@link AbstractChangeRunnerBuilder} bean.
*/
@Configuration
@ConditionalOnClass(name = "org.springframework.boot.SpringApplication")
@@ -50,56 +55,16 @@
public class FlamingockAutoConfiguration {
/**
- * Creates an ApplicationRunner that builds and executes Flamingock at application startup.
- * Only created when management-mode is APPLICATION_RUNNER (the default).
- */
- @Bean("flamingock-runner")
- @ConditionalOnExpression("'${flamingock.management-mode:APPLICATION_RUNNER}'.toUpperCase().equals('APPLICATION_RUNNER')")
- public ApplicationRunner applicationRunner(SpringbootProperties configurationProperties,
- ApplicationContext springContext,
- ApplicationEventPublisher applicationEventPublisher,
- @Autowired(required = false) CommunityAuditStore auditStore,
- List targetSystems) {
- AbstractChangeRunnerBuilder, ?> builder = createBuilder(
- configurationProperties, springContext, applicationEventPublisher, auditStore, targetSystems);
- return SpringbootUtil.toApplicationRunner(builder);
- }
-
- /**
- * Creates an InitializingBean that builds and executes Flamingock during bean initialization.
- * Only created when management-mode is INITIALIZING_BEAN.
- */
- @Bean("flamingock-runner")
- @ConditionalOnExpression("'${flamingock.management-mode:APPLICATION_RUNNER}'.toUpperCase().equals('INITIALIZING_BEAN')")
- public InitializingBean initializingBeanRunner(SpringbootProperties configurationProperties,
- ApplicationContext springContext,
- ApplicationEventPublisher applicationEventPublisher,
- @Autowired(required = false) CommunityAuditStore auditStore,
- List targetSystems) {
- AbstractChangeRunnerBuilder, ?> builder = createBuilder(
- configurationProperties, springContext, applicationEventPublisher, auditStore, targetSystems);
- return SpringbootUtil.toInitializingBean(builder);
- }
-
- /**
- * Exposes the Flamingock builder for manual control over execution.
- * Only created when management-mode is DEFERRED.
+ * Creates the Flamingock builder bean.
+ * Always created unless management-mode is UNMANAGED or user provides their own builder.
*/
@Bean("flamingock-builder")
- @ConditionalOnExpression("'${flamingock.management-mode:APPLICATION_RUNNER}'.toUpperCase().equals('DEFERRED')")
+ @ConditionalOnMissingBean(AbstractChangeRunnerBuilder.class)
public AbstractChangeRunnerBuilder, ?> flamingockBuilder(SpringbootProperties configurationProperties,
ApplicationContext springContext,
ApplicationEventPublisher applicationEventPublisher,
@Autowired(required = false) CommunityAuditStore auditStore,
List targetSystems) {
- return createBuilder(configurationProperties, springContext, applicationEventPublisher, auditStore, targetSystems);
- }
-
- private AbstractChangeRunnerBuilder, ?> createBuilder(SpringbootProperties configurationProperties,
- ApplicationContext springContext,
- ApplicationEventPublisher applicationEventPublisher,
- CommunityAuditStore auditStore,
- List targetSystems) {
AbstractChangeRunnerBuilder, ?> builder = FlamingockFactory.getEditionAwareBuilder(
configurationProperties.getCoreConfiguration(),
configurationProperties.getCloudProperties(),
@@ -116,4 +81,24 @@ public InitializingBean initializingBeanRunner(SpringbootProperties configuratio
return builder;
}
+
+ /**
+ * Creates an ApplicationRunner that builds and executes Flamingock at application startup.
+ * Only created when management-mode is APPLICATION_RUNNER (the default).
+ */
+ @Bean("flamingock-runner")
+ @ConditionalOnExpression("'${flamingock.management-mode:APPLICATION_RUNNER}'.toUpperCase().equals('APPLICATION_RUNNER')")
+ public ApplicationRunner applicationRunner(AbstractChangeRunnerBuilder, ?> builder) {
+ return SpringbootUtil.toApplicationRunner(builder);
+ }
+
+ /**
+ * Creates an InitializingBean that builds and executes Flamingock during bean initialization.
+ * Only created when management-mode is INITIALIZING_BEAN.
+ */
+ @Bean("flamingock-runner")
+ @ConditionalOnExpression("'${flamingock.management-mode:APPLICATION_RUNNER}'.toUpperCase().equals('INITIALIZING_BEAN')")
+ public InitializingBean initializingBeanRunner(AbstractChangeRunnerBuilder, ?> builder) {
+ return SpringbootUtil.toInitializingBean(builder);
+ }
}
diff --git a/platform-plugins/flamingock-springboot-integration/src/test/java/io/flamingock/springboot/FlamingockAutoConfigurationTests.java b/platform-plugins/flamingock-springboot-integration/src/test/java/io/flamingock/springboot/FlamingockAutoConfigurationTests.java
index 0d0e2ca33..a4f8e7baa 100644
--- a/platform-plugins/flamingock-springboot-integration/src/test/java/io/flamingock/springboot/FlamingockAutoConfigurationTests.java
+++ b/platform-plugins/flamingock-springboot-integration/src/test/java/io/flamingock/springboot/FlamingockAutoConfigurationTests.java
@@ -42,29 +42,29 @@ private ApplicationContextRunner contextRunner() {
}
@Test
- void whenModeIsDefault_thenRunnerBeanExistsAndBuilderBeanDoesNot() {
- // Default is APPLICATION_RUNNER - runner bean exists, builder bean does not
+ void whenModeIsDefault_thenBothBuilderAndRunnerBeansExist() {
+ // Default is APPLICATION_RUNNER - both builder and runner beans exist
contextRunner().run(ctx -> {
+ assertThat(ctx).hasBean("flamingock-builder");
assertThat(ctx).hasBean("flamingock-runner");
- assertThat(ctx).doesNotHaveBean("flamingock-builder");
});
}
@Test
- void whenModeIsApplicationRunner_thenRunnerBeanExistsAndBuilderBeanDoesNot() {
+ void whenModeIsApplicationRunner_thenBothBuilderAndRunnerBeansExist() {
contextRunner()
.withPropertyValues("flamingock.management-mode=APPLICATION_RUNNER")
.run(ctx -> {
+ assertThat(ctx).hasBean("flamingock-builder");
assertThat(ctx).hasBean("flamingock-runner");
- assertThat(ctx).doesNotHaveBean("flamingock-builder");
});
}
@Test
- void whenModeIsInitializingBean_thenRunnerBeanIsCreated() {
+ void whenModeIsInitializingBean_thenBothBeansCreatedAndExecutionAttempted() {
// InitializingBean executes immediately during bean creation.
- // We verify the bean creation was attempted by checking the context fails
- // with a Flamingock-related error (proving the InitializingBean bean was created and executed).
+ // Both builder and runner beans are created, but execution fails because
+ // the test context doesn't have all required Flamingock dependencies.
contextRunner()
.withPropertyValues("flamingock.management-mode=INITIALIZING_BEAN")
.run(ctx -> {