Polish "Add profile expression support"

Issue: SPR-12458
This commit is contained in:
Stephane Nicoll
2018-06-13 11:04:23 +02:00
parent e2623b7d35
commit 1f3b4f1863
13 changed files with 258 additions and 83 deletions

View File

@@ -7664,6 +7664,22 @@ straight JNDI `InitialContext` usage shown above, but not the `JndiObjectFactory
variant which would force you to declare the return type as the `FactoryBean` type.
====
The profile string may contains a simple profile name (for example `production`) or a
profile expression. A profile expression allows for more complicated profile logic to be
expressed, for example `production & us-east`. The following operators are supported in
profile expressions:
* `!` - A logical not of the profile
* `&` - A logical and of the profiles
* `|` - A logical or of the profiles
[NOTE]
====
The `&` and `|` operators may not be mixed without using parentheses. For example
`production & us-east | eu-central` is not a valid expression, it must be expressed as
`production & (us-east | eu-central)`.
====
`@Profile` can be used as a <<beans-meta-annotations,meta-annotation>> for the purpose
of creating a custom _composed annotation_. The following example defines a custom
`@Production` annotation that can be used as a drop-in replacement for
@@ -7804,6 +7820,35 @@ The `spring-bean.xsd` has been constrained to allow such elements only as the
last ones in the file. This should help provide flexibility without incurring
clutter in the XML files.
[NOTE]
====
The XML counterpart does not support profile expressions described above. It is possible
however to negate a profile using the `!` operator. It is also possible to apply a logical
and by nesting the profiles:
[source,xml,indent=0]
[subs="verbatim,quotes"]
----
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="...">
<!-- other bean definitions -->
<beans profile="production">
<beans profile="us-east">
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>
</beans>
</beans>
</beans>
----
In the example above, the `dataSource` bean will be exposed if both the `production` and
`us-east` profiles are active.
====
[[beans-definition-profiles-enable]]
==== Activating a profile

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -305,6 +305,37 @@ public class EnvironmentSystemIntegrationTests {
assertThat("should not have transitive bean", ctx.containsBean(TRANSITIVE_BEAN_NAME), is(false));
}
@Test
public void annotationConfigApplicationContext_withProfileExpressionMatchOr() {
testProfileExpression(true, "p3");
}
@Test
public void annotationConfigApplicationContext_withProfileExpressionMatchAnd() {
testProfileExpression(true, "p1", "p2");
}
@Test
public void annotationConfigApplicationContext_withProfileExpressionNoMatchAnd() {
testProfileExpression(false, "p1");
}
@Test
public void annotationConfigApplicationContext_withProfileExpressionNoMatchNone() {
testProfileExpression(false, "p4");
}
private void testProfileExpression(boolean expected, String... activeProfiles) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
StandardEnvironment environment = new StandardEnvironment();
environment.setActiveProfiles(activeProfiles);
ctx.setEnvironment(environment);
ctx.register(ProfileExpressionConfig.class);
ctx.refresh();
assertThat("wrong presence of expression bean",
ctx.containsBean("expressionBean"), is(expected));
}
@Test
public void webApplicationContext() {
GenericWebApplicationContext ctx = new GenericWebApplicationContext(newBeanFactoryWithEnvironmentAwareBean());
@@ -644,6 +675,15 @@ public class EnvironmentSystemIntegrationTests {
}
}
@Profile("(p1 & p2) | p3")
@Configuration
static class ProfileExpressionConfig {
@Bean
public Object expressionBean() {
return new Object();
}
}
/**
* Constants used both locally and in scan* sub-packages