diff --git a/spring-boot-modules/spring-boot-annotations/pom.xml b/spring-boot-modules/spring-boot-annotations/pom.xml
index b495c5de04..22572e7492 100644
--- a/spring-boot-modules/spring-boot-annotations/pom.xml
+++ b/spring-boot-modules/spring-boot-annotations/pom.xml
@@ -24,6 +24,10 @@
org.springframework.boot
spring-boot-starter-web
+
+ org.springframework.boot
+ spring-boot-autoconfigure
+
org.springframework.boot
spring-boot-starter-data-jpa
@@ -44,6 +48,11 @@
spring-boot-starter-test
test
+
+ org.mockito
+ mockito-inline
+ test
+
\ No newline at end of file
diff --git a/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/AdditionalWebConfiguration.java b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/AdditionalWebConfiguration.java
new file mode 100644
index 0000000000..22b41a28e0
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/AdditionalWebConfiguration.java
@@ -0,0 +1,9 @@
+package com.baeldung.annotations.conditional;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWarDeployment;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConditionalOnWarDeployment
+public class AdditionalWebConfiguration {
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/ConditionalUtils.java b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/ConditionalUtils.java
new file mode 100644
index 0000000000..7294d843d1
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/ConditionalUtils.java
@@ -0,0 +1,20 @@
+package com.baeldung.annotations.conditional;
+
+import org.apache.commons.lang3.SystemUtils;
+import org.springframework.boot.system.JavaVersion;
+
+public class ConditionalUtils {
+
+ public static boolean isWindows() {
+ return SystemUtils.IS_OS_WINDOWS;
+ }
+
+ public static boolean isJava8() {
+ return JavaVersion.getJavaVersion().equals(JavaVersion.EIGHT);
+ }
+
+ public static boolean isJava9() {
+ return JavaVersion.getJavaVersion().equals(JavaVersion.NINE);
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/DevEnvLoggingConfiguration.java b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/DevEnvLoggingConfiguration.java
new file mode 100644
index 0000000000..39f1d568f0
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/DevEnvLoggingConfiguration.java
@@ -0,0 +1,16 @@
+package com.baeldung.annotations.conditional;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@Conditional(IsDevEnvCondition.class)
+public class DevEnvLoggingConfiguration {
+
+ @Bean
+ @Conditional(IsDevEnvCondition.class)
+ LoggingService loggingService() {
+ return new LoggingService();
+ }
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/IsDevEnvCondition.java b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/IsDevEnvCondition.java
new file mode 100644
index 0000000000..768cd9f6ed
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/IsDevEnvCondition.java
@@ -0,0 +1,13 @@
+package com.baeldung.annotations.conditional;
+
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class IsDevEnvCondition implements Condition {
+
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ return "dev".equals(System.getProperty("env"));
+ }
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/IsWindowsCondition.java b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/IsWindowsCondition.java
new file mode 100644
index 0000000000..24aa4f4b1c
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/IsWindowsCondition.java
@@ -0,0 +1,13 @@
+package com.baeldung.annotations.conditional;
+
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class IsWindowsCondition implements Condition {
+
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ return ConditionalUtils.isWindows();
+ }
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java8Condition.java b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java8Condition.java
new file mode 100644
index 0000000000..c5f5e16d52
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java8Condition.java
@@ -0,0 +1,13 @@
+package com.baeldung.annotations.conditional;
+
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class Java8Condition implements Condition {
+
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ return ConditionalUtils.isJava8();
+ }
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java8DependedService.java b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java8DependedService.java
new file mode 100644
index 0000000000..ab76dcd930
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java8DependedService.java
@@ -0,0 +1,9 @@
+package com.baeldung.annotations.conditional;
+
+import org.springframework.context.annotation.Conditional;
+import org.springframework.stereotype.Service;
+
+@Service
+@Conditional(Java8Condition.class)
+public class Java8DependedService {
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java8OrJava9.java b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java8OrJava9.java
new file mode 100644
index 0000000000..77c501ed08
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java8OrJava9.java
@@ -0,0 +1,16 @@
+package com.baeldung.annotations.conditional;
+
+import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
+import org.springframework.context.annotation.Conditional;
+
+public class Java8OrJava9 extends AnyNestedCondition {
+ Java8OrJava9() {
+ super(ConfigurationPhase.REGISTER_BEAN);
+ }
+
+ @Conditional(Java8Condition.class)
+ static class Java8 { }
+
+ @Conditional(Java9Condition.class)
+ static class Java9 { }
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java9Condition.java b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java9Condition.java
new file mode 100644
index 0000000000..2afa8b25a7
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/Java9Condition.java
@@ -0,0 +1,13 @@
+package com.baeldung.annotations.conditional;
+
+import org.springframework.context.annotation.Condition;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class Java9Condition implements Condition {
+
+ @Override
+ public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
+ return ConditionalUtils.isJava9();
+ }
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/LoggingService.java b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/LoggingService.java
new file mode 100644
index 0000000000..e104ec86e1
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/main/java/com/baeldung/annotations/conditional/LoggingService.java
@@ -0,0 +1,19 @@
+package com.baeldung.annotations.conditional;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnJava;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.system.JavaVersion;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.stereotype.Service;
+
+@Service
+@Conditional({IsDevEnvCondition.class, IsWindowsCondition.class, Java8Condition.class})
+@ConditionalOnProperty(
+ value = "logging.enabled",
+ havingValue = "true",
+ matchIfMissing = true)
+@ConditionalOnExpression("${logging.enabled:true} and '${logging.level}'.equals('DEBUG')")
+@ConditionalOnJava(JavaVersion.EIGHT)
+public class LoggingService {
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/ConditionalTestConfiguration.java b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/ConditionalTestConfiguration.java
new file mode 100644
index 0000000000..6b23433422
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/ConditionalTestConfiguration.java
@@ -0,0 +1,10 @@
+package com.baeldung.annotations.conditional;
+
+import org.springframework.boot.test.context.TestConfiguration;
+import org.springframework.context.annotation.ComponentScan;
+
+@TestConfiguration
+@ComponentScan("com.baeldung.annotations.conditional")
+public class ConditionalTestConfiguration {
+
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/DevEnvLoggingConfigurationUnitTest.java b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/DevEnvLoggingConfigurationUnitTest.java
new file mode 100644
index 0000000000..e7c1975127
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/DevEnvLoggingConfigurationUnitTest.java
@@ -0,0 +1,52 @@
+package com.baeldung.annotations.conditional;
+
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+
+public class DevEnvLoggingConfigurationUnitTest {
+
+ private final ApplicationContextRunner contextRunner = new ApplicationContextRunner();
+
+ @Test
+ public void whenDevEnvEnabled_thenDevEnvLoggingConfigurationAndLoggingServiceShouldBeCreated() {
+ System.setProperty("env", "dev");
+
+ contextRunner
+ .withUserConfiguration(ConditionalTestConfiguration.class)
+ .run(context ->
+ Assertions.assertNotNull(
+ context.getBean(DevEnvLoggingConfiguration.class)
+ )
+ );
+ contextRunner
+ .withUserConfiguration(ConditionalTestConfiguration.class)
+ .run(context ->
+ Assertions.assertNotNull(
+ context.getBean(LoggingService.class)
+ )
+ );
+ }
+
+ @Test
+ public void whenDevEnvNotEnabled_thenDevEnvLoggingConfigurationAndLoggingServiceShouldNotBeCreated() {
+ System.setProperty("env", "not-dev");
+
+ contextRunner
+ .withUserConfiguration(ConditionalTestConfiguration.class)
+ .run(context ->
+ Assertions.assertThrows(NoSuchBeanDefinitionException.class, () ->
+ context.getBean(DevEnvLoggingConfiguration.class)
+ )
+ );
+ contextRunner
+ .withUserConfiguration(ConditionalTestConfiguration.class)
+ .run(context ->
+ Assertions.assertThrows(NoSuchBeanDefinitionException.class, () ->
+ context.getBean(LoggingService.class)
+ )
+ );
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/IsDevEnvConditionUnitTest.java b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/IsDevEnvConditionUnitTest.java
new file mode 100644
index 0000000000..5302fc79dd
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/IsDevEnvConditionUnitTest.java
@@ -0,0 +1,33 @@
+package com.baeldung.annotations.conditional;
+
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class IsDevEnvConditionUnitTest {
+
+ @Test
+ public void whenDevEnvEnabled_thenDevEnvConditionShouldPass() {
+ System.setProperty("env", "dev");
+
+ Assertions.assertTrue(
+ new IsDevEnvCondition().matches(
+ Mockito.mock(ConditionContext.class), Mockito.mock(AnnotatedTypeMetadata.class)
+ )
+ );
+ }
+
+ @Test
+ public void whenDevEnvNotEnabled_thenDevEnvConditionShouldNotPass() {
+ System.setProperty("env", "not-dev");
+
+ Assertions.assertFalse(
+ new IsDevEnvCondition().matches(
+ Mockito.mock(ConditionContext.class), Mockito.mock(AnnotatedTypeMetadata.class)
+ )
+ );
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/IsWindowsConditionUnitTest.java b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/IsWindowsConditionUnitTest.java
new file mode 100644
index 0000000000..45ae65a0e2
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/IsWindowsConditionUnitTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.annotations.conditional;
+
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class IsWindowsConditionUnitTest {
+
+ @Test
+ public void whenOnWindows_thenIsWindowsConditionShouldPass() {
+ try (MockedStatic theMock = Mockito.mockStatic(ConditionalUtils.class)) {
+ theMock.when(ConditionalUtils::isWindows)
+ .thenReturn(true);
+ Assertions.assertTrue(
+ new IsWindowsCondition().matches(
+ Mockito.mock(ConditionContext.class), Mockito.mock(AnnotatedTypeMetadata.class)
+ )
+ );
+ }
+
+ }
+
+ @Test
+ public void whenNotOnWindows_thenIsWindowsConditionShouldNotPass() {
+ try (MockedStatic theMock = Mockito.mockStatic(ConditionalUtils.class)) {
+ theMock.when(ConditionalUtils::isWindows)
+ .thenReturn(false);
+ Assertions.assertFalse(
+ new IsWindowsCondition().matches(
+ Mockito.mock(ConditionContext.class), Mockito.mock(AnnotatedTypeMetadata.class)
+ )
+ );
+ }
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/Java8ConditionUnitTest.java b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/Java8ConditionUnitTest.java
new file mode 100644
index 0000000000..0d1b1eded6
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/Java8ConditionUnitTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.annotations.conditional;
+
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class Java8ConditionUnitTest {
+
+ @Test
+ public void whenOnJava8_thenJava8ConditionShouldPass() {
+ try (MockedStatic theMock = Mockito.mockStatic(ConditionalUtils.class)) {
+ theMock.when(ConditionalUtils::isJava8)
+ .thenReturn(true);
+ Assertions.assertTrue(
+ new Java8Condition().matches(
+ Mockito.mock(ConditionContext.class), Mockito.mock(AnnotatedTypeMetadata.class)
+ )
+ );
+ }
+
+ }
+
+ @Test
+ public void whenNotOnJava8_thenJava8ConditionShouldNotPass() {
+ try (MockedStatic theMock = Mockito.mockStatic(ConditionalUtils.class)) {
+ theMock.when(ConditionalUtils::isJava8)
+ .thenReturn(false);
+ Assertions.assertFalse(
+ new Java8Condition().matches(
+ Mockito.mock(ConditionContext.class), Mockito.mock(AnnotatedTypeMetadata.class)
+ )
+ );
+ }
+ }
+
+}
diff --git a/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/Java9ConditionUnitTest.java b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/Java9ConditionUnitTest.java
new file mode 100644
index 0000000000..ce277e81fe
--- /dev/null
+++ b/spring-boot-modules/spring-boot-annotations/src/test/java/com/baeldung/annotations/conditional/Java9ConditionUnitTest.java
@@ -0,0 +1,39 @@
+package com.baeldung.annotations.conditional;
+
+import org.junit.Test;
+import org.junit.jupiter.api.Assertions;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.type.AnnotatedTypeMetadata;
+
+public class Java9ConditionUnitTest {
+
+ @Test
+ public void whenOnJava9_thenJava9ConditionShouldPass() {
+ try (MockedStatic theMock = Mockito.mockStatic(ConditionalUtils.class)) {
+ theMock.when(ConditionalUtils::isJava9)
+ .thenReturn(true);
+ Assertions.assertTrue(
+ new Java9Condition().matches(
+ Mockito.mock(ConditionContext.class), Mockito.mock(AnnotatedTypeMetadata.class)
+ )
+ );
+ }
+
+ }
+
+ @Test
+ public void whenNotOnJava9_thenJava9ConditionShouldNotPass() {
+ try (MockedStatic theMock = Mockito.mockStatic(ConditionalUtils.class)) {
+ theMock.when(ConditionalUtils::isJava9)
+ .thenReturn(false);
+ Assertions.assertFalse(
+ new Java9Condition().matches(
+ Mockito.mock(ConditionContext.class), Mockito.mock(AnnotatedTypeMetadata.class)
+ )
+ );
+ }
+ }
+
+}