diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/AopAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/AopAutoConfiguration.java
index d8447a6acf3..f59ec29bdda 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/AopAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/aop/AopAutoConfiguration.java
@@ -19,7 +19,6 @@ package org.springframework.boot.autoconfigure.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.Advice;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@@ -40,19 +39,18 @@ import org.springframework.context.annotation.EnableAspectJAutoProxy;
*/
@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
-@ConditionalOnProperty(value = "spring.aop.auto", match = "true", defaultMatch = true)
+@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = false)
- @ConditionalOnProperty(value = "spring.aop.proxyTargetClass", match = "false", defaultMatch = true)
+ @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = true)
public static class JdkDynamicAutoProxyConfiguration {
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
- @ConditionalOnExpression("${spring.aop.proxyTargetClass:false}")
- @ConditionalOnProperty(value = "spring.aop.proxyTargetClass", match = "true", defaultMatch = false)
+ @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = false)
public static class CglibAutoProxyConfiguration {
}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java
index 278f3261b2e..5dc30d5d3ba 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java
@@ -78,7 +78,7 @@ public class BatchAutoConfiguration {
@Bean
@ConditionalOnMissingBean
- @ConditionalOnProperty(value = "spring.batch.job.enabled", match = "true", defaultMatch = true)
+ @ConditionalOnProperty(prefix = "spring.batch.job", name = "enabled", havingValue = "true", matchIfMissing = true)
public JobLauncherCommandLineRunner jobLauncherCommandLineRunner(
JobLauncher jobLauncher, JobExplorer jobExplorer) {
JobLauncherCommandLineRunner runner = new JobLauncherCommandLineRunner(
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnProperty.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnProperty.java
index 9f00db0a57e..e7cd7c3e8c1 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnProperty.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/ConditionalOnProperty.java
@@ -25,66 +25,56 @@ import org.springframework.context.annotation.Conditional;
import org.springframework.core.env.Environment;
/**
- * {@link Conditional} that checks if the specified properties
- * have the requested matching value. By default the properties
- * must be present in the {@link Environment} ant not
- * equal to {@code false}. The {@link #match()} and {@link #defaultMatch()}
- * attributes allow to further customize the condition.
+ * {@link Conditional} that checks if the specified properties have a specific value. By
+ * default the properties must be present in the {@link Environment} and
+ * not equal to {@code false}. The {@link #havingValue()} and
+ * {@link #matchIfMissing()} attributes allow further customizations.
*
- *
The {@link #match} attribute provides the value that the property
- * should have. The {@link #defaultMatch()} flag specifies if the
- * condition also matches if the property is not present
- * at all.
- *
- *
The table below defines when a condition match according to the
- * property value and the {@link #match()} value
+ *
+ * The {@link #havingValue} attribute can be used to specify the value that the property
+ * should have. The table below shows when a condition matches according to the property
+ * value and the {@link #havingValue()} attribute:
*
+ *
*
- * |
- * | no {@code match} value |
- * {@code true} |
- * {@code false} |
- * {@code foo} |
- *
- *
- * | not set ({@code defaultMatch = false}) |
- * no |
- * no |
- * no |
- * no |
- *
*
- * | not set ({@code defaultMatch = true}) |
- * yes |
- * yes |
- * yes |
- * yes |
+ * Property Value |
+ * {@code havingValue=""} |
+ * {@code havingValue="true"} |
+ * {@code havingValue="false"} |
+ * {@code havingValue="foo"} |
*
*
- * | {@code true} |
- * yes |
- * yes |
- * no |
- * no |
+ * {@code "true"} |
+ * yes |
+ * yes |
+ * no |
+ * no |
*
*
- * | {@code false} |
- * no |
- * no |
- * yes |
- * no |
+ * {@code "false"} |
+ * no |
+ * no |
+ * yes |
+ * no |
*
*
- * | {@code foo} |
- * yes |
- * no |
- * no |
- * yes |
+ * {@code "foo"} |
+ * yes |
+ * no |
+ * no |
+ * yes |
*
*
*
+ *
+ * If the property is not contained in the {@link Environment} at all, the
+ * {@link #matchIfMissing()} attribute is consulted. By default missing attributes do not
+ * match.
+ *
* @author Maciej Walkowiak
* @author Stephane Nicoll
+ * @author Phillip Webb
* @since 1.1.0
*/
@Conditional(OnPropertyCondition.class)
@@ -93,38 +83,38 @@ import org.springframework.core.env.Environment;
public @interface ConditionalOnProperty {
/**
- * A prefix that should be applied to each property.
- *
Defaults to no prefix. The prefix automatically
- * ends with a dot if not specified.
+ * Alias for {@link #name()}.
+ */
+ String[] value() default {};
+
+ /**
+ * A prefix that should be applied to each property. The prefix automatically ends
+ * with a dot if not specified.
*/
String prefix() default "";
/**
- * One or more properties to validate against the
- * {@link #match} value. If a prefix has been defined, it
- * is applied to compute the full key of each property. For
- * instance if the prefix is {@code app.config} and one
- * value is {@code my-value}, the fully key would be
+ * The name of the properties to test.If a prefix has been defined, it is applied to
+ * compute the full key of each property. For instance if the prefix is
+ * {@code app.config} and one value is {@code my-value}, the fully key would be
* {@code app.config.my-value}
- *
Use the dashed notation to specify each property, that
- * is all lower case with a "-" to separate words (e.g.
- * {@code my-long-property}).
- * @return the property names
+ *
+ * Use the dashed notation to specify each property, that is all lower case with a "-"
+ * to separate words (e.g. {@code my-long-property}).
*/
- String[] value();
+ String[] name() default {};
/**
- * The string representation of the expected value for the
- * properties. If not specified, the property must
- * not be equals to {@code false}
+ * The string representation of the expected value for the properties. If not
+ * specified, the property must not be equals to {@code false}
*/
- String match() default "";
+ String havingValue() default "";
/**
- * Specify if the condition should match if the property is not set.
- * Defaults to {@code false}
+ * Specify if the condition should match if the property is not set. Defaults to
+ * {@code false}
*/
- boolean defaultMatch() default false;
+ boolean matchIfMissing() default false;
/**
* If relaxed names should be checked. Defaults to {@code true}.
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnPropertyCondition.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnPropertyCondition.java
index cdc8c820eb2..122e6715caa 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnPropertyCondition.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/condition/OnPropertyCondition.java
@@ -23,8 +23,10 @@ import java.util.Map;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
+import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.PropertyResolver;
import org.springframework.core.type.AnnotatedTypeMetadata;
+import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -42,41 +44,35 @@ class OnPropertyCondition extends SpringBootCondition {
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
- Map annotationAttributes = metadata.getAnnotationAttributes(
- ConditionalOnProperty.class.getName());
+ AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(metadata
+ .getAnnotationAttributes(ConditionalOnProperty.class.getName()));
- String prefix = getPrefix(annotationAttributes);
- String expectedValue = getExpectedValue(annotationAttributes);
- String[] names = (String[]) annotationAttributes.get("value");
- boolean relaxedNames = (Boolean) annotationAttributes.get("relaxedNames");
- boolean matchDefault = (Boolean) annotationAttributes.get("defaultMatch");
-
- List missingProperties = new ArrayList();
- List nonMatchingProperties = new ArrayList();
+ String prefix = annotationAttributes.getString("prefix").trim();
+ if (StringUtils.hasText(prefix) && !prefix.endsWith(".")) {
+ prefix = prefix + ".";
+ }
+ String havingValue = annotationAttributes.getString("havingValue");
+ String[] names = getNames(annotationAttributes);
+ boolean relaxedNames = annotationAttributes.getBoolean("relaxedNames");
+ boolean matchIfMissing = annotationAttributes.getBoolean("matchIfMissing");
PropertyResolver resolver = context.getEnvironment();
if (relaxedNames) {
resolver = new RelaxedPropertyResolver(resolver, prefix);
- prefix = "";
}
+ List missingProperties = new ArrayList();
+ List nonMatchingProperties = new ArrayList();
for (String name : names) {
- name = prefix + name;
- boolean hasProperty = resolver.containsProperty(name);
- if (!hasProperty) { // property not set
- if (!matchDefault) { // property is mandatory
- missingProperties.add(name);
+ String key = (relaxedNames ? name : prefix + name);
+ if (resolver.containsProperty(key)) {
+ if (!isMatch(resolver.getProperty(key), havingValue)) {
+ nonMatchingProperties.add(name);
}
}
else {
- String actualValue = resolver.getProperty(name);
- if (expectedValue == null) {
- if ("false".equalsIgnoreCase(actualValue)) {
- nonMatchingProperties.add(name);
- }
- }
- else if (!expectedValue.equalsIgnoreCase(actualValue)) {
- nonMatchingProperties.add(name);
+ if (!matchIfMissing) {
+ missingProperties.add(name);
}
}
}
@@ -85,42 +81,45 @@ class OnPropertyCondition extends SpringBootCondition {
return ConditionOutcome.match();
}
- StringBuilder sb = new StringBuilder("@ConditionalOnProperty ");
- if (!matchDefault && !missingProperties.isEmpty()) {
- sb.append("missing required properties ")
- .append(StringUtils.arrayToCommaDelimitedString(missingProperties.toArray()))
- .append(" ");
+ StringBuilder message = new StringBuilder("@ConditionalOnProperty ");
+ if (!missingProperties.isEmpty()) {
+ message.append("missing required properties "
+ + expandNames(prefix, missingProperties) + " ");
}
if (!nonMatchingProperties.isEmpty()) {
- String expected = expectedValue == null ? "!false" : expectedValue;
- sb.append("expected '").append(expected).append("' for properties: ")
- .append(StringUtils.arrayToCommaDelimitedString(nonMatchingProperties.toArray()));
+ String expected = havingValue == null ? "!false" : havingValue;
+ message.append("expected '").append(expected).append("' for properties ")
+ .append(expandNames(prefix, nonMatchingProperties));
}
- return ConditionOutcome.noMatch(sb.toString());
+ return ConditionOutcome.noMatch(message.toString());
}
- /**
- * Return the prefix to use or an empty String if it's not set.
- * Add a dot at the end if it is not present already.
- */
- private static String getPrefix(Map annotationAttributes) {
- String prefix = ((String) annotationAttributes.get("prefix")).trim();
- if (StringUtils.hasText(prefix) && !prefix.endsWith(".")) {
- prefix = prefix + ".";
+ private String[] getNames(Map annotationAttributes) {
+ String[] value = (String[]) annotationAttributes.get("value");
+ String[] name = (String[]) annotationAttributes.get("name");
+ Assert.state(value.length > 0 || name.length > 0,
+ "The name or value attribute of @ConditionalOnProperty must be specified");
+ Assert.state(value.length == 0 || name.length == 0,
+ "The name and value attributes of @ConditionalOnProperty are exclusive");
+ return (value.length > 0 ? value : name);
+ }
+
+ private boolean isMatch(String value, String requiredValue) {
+ if (StringUtils.hasLength(requiredValue)) {
+ return requiredValue.equalsIgnoreCase(value);
}
- return prefix;
+ return !"false".equalsIgnoreCase(value);
}
- /**
- * Return the expected value to match against or {@code null} if no
- * match value is set.
- */
- private static String getExpectedValue(Map annotationAttributes) {
- String match = (String) annotationAttributes.get("match");
- if (StringUtils.hasText(match)) {
- return match;
+ private String expandNames(String prefix, List names) {
+ StringBuffer expanded = new StringBuffer();
+ for (String name : names) {
+ expanded.append(expanded.length() == 0 ? "" : ", ");
+ expanded.append(prefix);
+ expanded.append(name);
}
- return null;
+ return expanded.toString();
}
+
}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfiguration.java
index 1b0e982f078..3d5bcc63b0c 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchRepositoriesAutoConfiguration.java
@@ -38,8 +38,7 @@ import org.springframework.data.repository.core.support.RepositoryFactoryBeanSup
*/
@Configuration
@ConditionalOnClass({ Client.class, ElasticsearchRepository.class })
-@ConditionalOnProperty(value = "spring.data.elasticsearch.repositories.enabled",
- match = "true", defaultMatch = true)
+@ConditionalOnProperty(prefix = "spring.data.elasticsearch.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnMissingBean(RepositoryFactoryBeanSupport.class)
@Import(ElasticsearchRepositoriesAutoConfigureRegistrar.class)
public class ElasticsearchRepositoriesAutoConfiguration {
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.java
index 074728ea4ea..983bea005d9 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/jpa/JpaRepositoriesAutoConfiguration.java
@@ -59,7 +59,7 @@ import org.springframework.data.web.config.EnableSpringDataWebSupport;
@ConditionalOnClass(JpaRepository.class)
@ConditionalOnMissingBean({ RepositoryFactoryBeanSupport.class,
JpaRepositoryConfigExtension.class })
-@ConditionalOnProperty(value = "spring.data.jpa.repositories.enabled", match = "true", defaultMatch = true)
+@ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
@Import(JpaRepositoriesAutoConfigureRegistrar.class)
@AutoConfigureAfter(HibernateJpaAutoConfiguration.class)
public class JpaRepositoriesAutoConfiguration {
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java
index c222236f19b..1a135c2df9f 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/mongo/MongoRepositoriesAutoConfiguration.java
@@ -56,7 +56,7 @@ import com.mongodb.Mongo;
@ConditionalOnClass({ Mongo.class, MongoRepository.class })
@ConditionalOnMissingBean({ RepositoryFactoryBeanSupport.class,
MongoRepositoryConfigurationExtension.class })
-@ConditionalOnProperty(value = "spring.data.mongo.repositories.enabled", match = "true", defaultMatch = true)
+@ConditionalOnProperty(prefix = "spring.data.mongo.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
@Import(MongoRepositoriesAutoConfigureRegistrar.class)
@AutoConfigureAfter(MongoAutoConfiguration.class)
public class MongoRepositoriesAutoConfiguration {
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfiguration.java
index 4aebec341db..765f2fe8699 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/data/solr/SolrRepositoriesAutoConfiguration.java
@@ -47,7 +47,7 @@ import org.springframework.data.solr.repository.config.SolrRepositoryConfigExten
@ConditionalOnClass({ SolrServer.class, SolrRepository.class })
@ConditionalOnMissingBean({ RepositoryFactoryBeanSupport.class,
SolrRepositoryConfigExtension.class })
-@ConditionalOnProperty(value = "spring.data.solr.repositories.enabled", match = "true", defaultMatch = true)
+@ConditionalOnProperty(prefix = "spring.data.solr.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
@Import(SolrRepositoriesAutoConfigureRegistrar.class)
public class SolrRepositoriesAutoConfiguration {
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java
index 974e64d1797..c594c268b99 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java
@@ -51,7 +51,7 @@ public class IntegrationAutoConfiguration {
@Configuration
@ConditionalOnClass(EnableIntegrationMBeanExport.class)
@ConditionalOnMissingBean(value = IntegrationMBeanExporter.class, search = SearchStrategy.CURRENT)
- @ConditionalOnProperty(value = "spring.jmx.enabled", match = "true", defaultMatch = true)
+ @ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true", matchIfMissing = true)
@EnableIntegrationMBeanExport(defaultDomain = "${spring.jmx.default_domain:}", server = "${spring.jmx.server:mbeanServer}")
protected static class IntegrationJmxConfiguration {
}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java
index 230212595d9..05f86311393 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java
@@ -53,7 +53,7 @@ import org.springframework.util.ClassUtils;
*/
@Configuration
@ConditionalOnClass({ MBeanExporter.class })
-@ConditionalOnProperty(value = "spring.jmx.enabled", match = "true", defaultMatch = true)
+@ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true", matchIfMissing = true)
public class JmxAutoConfiguration {
@Autowired
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/DeviceDelegatingViewResolverAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/DeviceDelegatingViewResolverAutoConfiguration.java
index d962c59c65a..f1a07193316 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/DeviceDelegatingViewResolverAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/DeviceDelegatingViewResolverAutoConfiguration.java
@@ -88,7 +88,7 @@ public class DeviceDelegatingViewResolverAutoConfiguration {
@Configuration
@EnableConfigurationProperties(DeviceDelegatingViewResolverProperties.class)
@ConditionalOnMissingBean(name = "deviceDelegatingViewResolver")
- @ConditionalOnProperty(value = "spring.mobile.devicedelegatingviewresolver.enabled", match = "true", defaultMatch = false)
+ @ConditionalOnProperty(prefix = "spring.mobile.devicedelegatingviewresolver", name = "enabled", havingValue = "true", matchIfMissing = false)
protected static class DeviceDelegatingViewResolverConfiguration {
@Configuration
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfiguration.java
index 49e60b4f468..bad97da902e 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mobile/SitePreferenceAutoConfiguration.java
@@ -47,7 +47,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
@ConditionalOnClass({ SitePreferenceHandlerInterceptor.class,
SitePreferenceHandlerMethodArgumentResolver.class })
@AutoConfigureAfter(DeviceResolverAutoConfiguration.class)
-@ConditionalOnProperty(value ="spring.mobile.sitepreference.enabled", match = "true", defaultMatch = true)
+@ConditionalOnProperty(prefix = "spring.mobile.sitepreference", name = "enabled", havingValue = "true", matchIfMissing = true)
public class SitePreferenceAutoConfiguration {
@Configuration
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java
index 0d4f94a01d1..dbcb6dd656b 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/orm/jpa/JpaBaseConfiguration.java
@@ -136,7 +136,7 @@ public abstract class JpaBaseConfiguration implements BeanFactoryAware {
@ConditionalOnWebApplication
@ConditionalOnMissingBean({ OpenEntityManagerInViewInterceptor.class,
OpenEntityManagerInViewFilter.class })
- @ConditionalOnProperty(prefix = "spring.jpa", value = "openInView", match = "true", defaultMatch = true)
+ @ConditionalOnProperty(prefix = "spring.jpa", name = "open-in-view", havingValue = "true", matchIfMissing = true)
protected static class JpaWebConfiguration extends WebMvcConfigurerAdapter {
@Override
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/FacebookAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/FacebookAutoConfiguration.java
index 12316d2f8e0..0e04cb90be1 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/FacebookAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/FacebookAutoConfiguration.java
@@ -50,7 +50,7 @@ import org.springframework.web.servlet.View;
*/
@Configuration
@ConditionalOnClass({ SocialConfigurerAdapter.class, FacebookConnectionFactory.class })
-@ConditionalOnProperty(prefix = "spring.social.facebook.", value = "app-id")
+@ConditionalOnProperty(prefix = "spring.social.facebook", name = "app-id")
@AutoConfigureBefore(SocialWebAutoConfiguration.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class FacebookAutoConfiguration {
@@ -75,7 +75,7 @@ public class FacebookAutoConfiguration {
}
@Bean(name = { "connect/facebookConnect", "connect/facebookConnected" })
- @ConditionalOnProperty(prefix = "spring.social.", value = "auto-connection-views")
+ @ConditionalOnProperty(prefix = "spring.social", name = "auto-connection-views")
public View facebookConnectView() {
return new GenericConnectionStatusView("facebook", "Facebook");
}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/LinkedInAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/LinkedInAutoConfiguration.java
index f9fb652ead1..73cb7b9889f 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/LinkedInAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/LinkedInAutoConfiguration.java
@@ -49,7 +49,7 @@ import org.springframework.web.servlet.View;
*/
@Configuration
@ConditionalOnClass({ SocialConfigurerAdapter.class, LinkedInConnectionFactory.class })
-@ConditionalOnProperty(prefix = "spring.social.linkedin.", value = "app-id")
+@ConditionalOnProperty(prefix = "spring.social.linkedin", name = "app-id")
@AutoConfigureBefore(SocialWebAutoConfiguration.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class LinkedInAutoConfiguration {
@@ -74,7 +74,7 @@ public class LinkedInAutoConfiguration {
}
@Bean(name = { "connect/linkedinConnect", "connect/linkedinConnected" })
- @ConditionalOnProperty(prefix = "spring.social.", value = "auto-connection-views")
+ @ConditionalOnProperty(prefix = "spring.social", name = "auto-connection-views")
public View linkedInConnectView() {
return new GenericConnectionStatusView("linkedin", "LinkedIn");
}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/SocialWebAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/SocialWebAutoConfiguration.java
index 8c6e9e52bff..a46a2a80ec5 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/SocialWebAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/SocialWebAutoConfiguration.java
@@ -99,7 +99,7 @@ public class SocialWebAutoConfiguration {
@Bean
@ConditionalOnMissingBean(BeanNameViewResolver.class)
- @ConditionalOnProperty(prefix = "spring.social.", value = "auto-connection-views")
+ @ConditionalOnProperty(prefix = "spring.social", name = "auto-connection-views")
public ViewResolver beanNameViewResolver() {
BeanNameViewResolver viewResolver = new BeanNameViewResolver();
viewResolver.setOrder(Integer.MIN_VALUE);
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/TwitterAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/TwitterAutoConfiguration.java
index fa008e891f3..dd6f394a508 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/TwitterAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/social/TwitterAutoConfiguration.java
@@ -50,7 +50,7 @@ import org.springframework.web.servlet.View;
*/
@Configuration
@ConditionalOnClass({ SocialConfigurerAdapter.class, TwitterConnectionFactory.class })
-@ConditionalOnProperty(prefix = "spring.social.twitter.", value = "app-id")
+@ConditionalOnProperty(prefix = "spring.social.twitter", name = "app-id")
@AutoConfigureBefore(SocialWebAutoConfiguration.class)
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class TwitterAutoConfiguration {
@@ -79,7 +79,7 @@ public class TwitterAutoConfiguration {
}
@Bean(name = { "connect/twitterConnect", "connect/twitterConnected" })
- @ConditionalOnProperty(prefix = "spring.social.", value = "auto-connection-views")
+ @ConditionalOnProperty(prefix = "spring.social", name = "auto-connection-views")
public View twitterConnectView() {
return new GenericConnectionStatusView("twitter", "Twitter");
}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java
index e545dcb435d..0ea0c91f21c 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java
@@ -197,14 +197,14 @@ public class WebMvcAutoConfiguration {
@Bean
@ConditionalOnMissingBean(LocaleResolver.class)
- @ConditionalOnProperty(prefix = "spring.mvc.", value = "locale")
+ @ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
return new FixedLocaleResolver(
StringUtils.parseLocaleString(this.mvcProperties.getLocale()));
}
@Bean
- @ConditionalOnProperty(prefix = "spring.mvc.", value = "date-format")
+ @ConditionalOnProperty(prefix = "spring.mvc", name = "date-format")
public Formatter dateFormatter() {
return new DateFormatter(this.mvcProperties.getDateFormat());
}
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnPropertyTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnPropertyTests.java
index b8381c798c3..89da1b27d7e 100644
--- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnPropertyTests.java
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/condition/ConditionalOnPropertyTests.java
@@ -17,23 +17,31 @@
package org.springframework.boot.autoconfigure.condition;
import org.junit.After;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.internal.matchers.ThrowableMessageMatcher.hasMessage;
/**
* Tests for {@link ConditionalOnProperty}.
*
* @author Maciej Walkowiak
* @author Stephane Nicoll
+ * @author Phillip Webb
*/
public class ConditionalOnPropertyTests {
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
private AnnotationConfigApplicationContext context;
@After
@@ -45,29 +53,28 @@ public class ConditionalOnPropertyTests {
@Test
public void allPropertiesAreDefined() {
- load(MultiplePropertiesRequiredConfiguration.class,
- "property1=value1", "property2=value2");
+ load(MultiplePropertiesRequiredConfiguration.class, "property1=value1",
+ "property2=value2");
assertTrue(this.context.containsBean("foo"));
}
@Test
public void notAllPropertiesAreDefined() {
- load(MultiplePropertiesRequiredConfiguration.class,
- "property1=value1");
+ load(MultiplePropertiesRequiredConfiguration.class, "property1=value1");
assertFalse(this.context.containsBean("foo"));
}
@Test
public void propertyValueEqualsFalse() {
- load(MultiplePropertiesRequiredConfiguration.class,
- "property1=false", "property2=value2");
+ load(MultiplePropertiesRequiredConfiguration.class, "property1=false",
+ "property2=value2");
assertFalse(this.context.containsBean("foo"));
}
@Test
public void propertyValueEqualsFALSE() {
- load(MultiplePropertiesRequiredConfiguration.class,
- "property1=FALSE", "property2=value2");
+ load(MultiplePropertiesRequiredConfiguration.class, "property1=FALSE",
+ "property2=value2");
assertFalse(this.context.containsBean("foo"));
}
@@ -87,12 +94,12 @@ public class ConditionalOnPropertyTests {
@Test
public void nonRelaxedName() throws Exception {
- load(NonRelaxedPropertiesRequiredConfiguration.class,
- "theRelaxedProperty=value1");
+ load(NonRelaxedPropertiesRequiredConfiguration.class, "theRelaxedProperty=value1");
assertFalse(this.context.containsBean("foo"));
}
- @Test // Enabled by default
+ @Test
+ // Enabled by default
public void enabledIfNotConfiguredOtherwise() {
load(EnabledIfNotConfiguredOtherwiseConfig.class);
assertTrue(this.context.containsBean("foo"));
@@ -110,7 +117,8 @@ public class ConditionalOnPropertyTests {
assertFalse(this.context.containsBean("foo"));
}
- @Test // Disabled by default
+ @Test
+ // Disabled by default
public void disableIfNotConfiguredOtherwise() {
load(DisabledIfNotConfiguredOtherwiseConfig.class);
assertFalse(this.context.containsBean("foo"));
@@ -184,7 +192,8 @@ public class ConditionalOnPropertyTests {
@Test
public void multiValuesAllSet() {
- load(MultiValuesConfig.class, "simple.my-property:bar", "simple.my-another-property:bar");
+ load(MultiValuesConfig.class, "simple.my-property:bar",
+ "simple.my-another-property:bar");
assertTrue(this.context.containsBean("foo"));
}
@@ -194,6 +203,28 @@ public class ConditionalOnPropertyTests {
assertFalse(this.context.containsBean("foo"));
}
+ @Test
+ public void usingValueAttribute() throws Exception {
+ load(ValueAttribute.class, "some.property");
+ assertTrue(this.context.containsBean("foo"));
+ }
+
+ @Test
+ public void nameOrValueMustBeSpecified() throws Exception {
+ this.thrown.expect(IllegalStateException.class);
+ this.thrown.expectCause(hasMessage(containsString("The name or "
+ + "value attribute of @ConditionalOnProperty must be specified")));
+ load(NoNameOrValueAttribute.class, "some.property");
+ }
+
+ @Test
+ public void nameAndValueMustNotBeSpecified() throws Exception {
+ this.thrown.expect(IllegalStateException.class);
+ this.thrown.expectCause(hasMessage(containsString("The name and "
+ + "value attributes of @ConditionalOnProperty are exclusive")));
+ load(NameAndValueAttribute.class, "some.property");
+ }
+
private void load(Class> config, String... environment) {
this.context = new AnnotationConfigApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context, environment);
@@ -201,9 +232,8 @@ public class ConditionalOnPropertyTests {
this.context.refresh();
}
-
@Configuration
- @ConditionalOnProperty({ "property1", "property2" })
+ @ConditionalOnProperty(name = { "property1", "property2" })
protected static class MultiplePropertiesRequiredConfiguration {
@Bean
@@ -214,7 +244,7 @@ public class ConditionalOnPropertyTests {
}
@Configuration
- @ConditionalOnProperty(prefix = "spring.", value = "the-relaxed-property")
+ @ConditionalOnProperty(prefix = "spring.", name = "the-relaxed-property")
protected static class RelaxedPropertiesRequiredConfiguration {
@Bean
@@ -225,7 +255,7 @@ public class ConditionalOnPropertyTests {
}
@Configuration
- @ConditionalOnProperty(prefix = "spring", value = "property")
+ @ConditionalOnProperty(prefix = "spring", name = "property")
protected static class RelaxedPropertiesRequiredConfigurationWithShortPrefix {
@Bean
@@ -236,7 +266,7 @@ public class ConditionalOnPropertyTests {
}
@Configuration
- @ConditionalOnProperty(value = "the-relaxed-property", relaxedNames = false)
+ @ConditionalOnProperty(name = "the-relaxed-property", relaxedNames = false)
protected static class NonRelaxedPropertiesRequiredConfiguration {
@Bean
@@ -246,8 +276,9 @@ public class ConditionalOnPropertyTests {
}
- @Configuration // ${simple.myProperty:true}
- @ConditionalOnProperty(prefix = "simple", value = "my-property", match = "true", defaultMatch = true)
+ @Configuration
+ // i.e ${simple.myProperty:true}
+ @ConditionalOnProperty(prefix = "simple", name = "my-property", havingValue = "true", matchIfMissing = true)
static class EnabledIfNotConfiguredOtherwiseConfig {
@Bean
@@ -257,8 +288,9 @@ public class ConditionalOnPropertyTests {
}
- @Configuration // ${simple.myProperty:false}
- @ConditionalOnProperty(prefix = "simple", value = "my-property", match = "true", defaultMatch = false)
+ @Configuration
+ // i.e ${simple.myProperty:false}
+ @ConditionalOnProperty(prefix = "simple", name = "my-property", havingValue = "true", matchIfMissing = false)
static class DisabledIfNotConfiguredOtherwiseConfig {
@Bean
@@ -269,7 +301,7 @@ public class ConditionalOnPropertyTests {
}
@Configuration
- @ConditionalOnProperty(prefix = "simple", value = "my-property", match = "bar")
+ @ConditionalOnProperty(prefix = "simple", name = "my-property", havingValue = "bar")
static class SimpleValueConfig {
@Bean
@@ -280,7 +312,7 @@ public class ConditionalOnPropertyTests {
}
@Configuration
- @ConditionalOnProperty(value = "simple.myProperty", match = "bar", defaultMatch = true)
+ @ConditionalOnProperty(name = "simple.myProperty", havingValue = "bar", matchIfMissing = true)
static class DefaultValueConfig {
@Bean
@@ -291,7 +323,7 @@ public class ConditionalOnPropertyTests {
}
@Configuration
- @ConditionalOnProperty(prefix = "simple", value = "my-property", match = "bar")
+ @ConditionalOnProperty(prefix = "simple", name = "my-property", havingValue = "bar")
static class PrefixValueConfig {
@Bean
@@ -302,7 +334,7 @@ public class ConditionalOnPropertyTests {
}
@Configuration
- @ConditionalOnProperty(prefix = "simple", value = "my-property", match = "bar", relaxedNames = false)
+ @ConditionalOnProperty(prefix = "simple", name = "my-property", havingValue = "bar", relaxedNames = false)
static class StrictNameConfig {
@Bean
@@ -313,7 +345,8 @@ public class ConditionalOnPropertyTests {
}
@Configuration
- @ConditionalOnProperty(prefix = "simple", value = {"my-property", "my-another-property"}, match = "bar")
+ @ConditionalOnProperty(prefix = "simple", name = { "my-property",
+ "my-another-property" }, havingValue = "bar")
static class MultiValuesConfig {
@Bean
@@ -323,4 +356,36 @@ public class ConditionalOnPropertyTests {
}
+ @Configuration
+ @ConditionalOnProperty("some.property")
+ protected static class ValueAttribute {
+
+ @Bean
+ public String foo() {
+ return "foo";
+ }
+
+ }
+
+ @Configuration
+ @ConditionalOnProperty
+ protected static class NoNameOrValueAttribute {
+
+ @Bean
+ public String foo() {
+ return "foo";
+ }
+
+ }
+
+ @Configuration
+ @ConditionalOnProperty(value = "x", name = "y")
+ protected static class NameAndValueAttribute {
+
+ @Bean
+ public String foo() {
+ return "foo";
+ }
+
+ }
}