Skip to content

Commit 3126a4c

Browse files
committed
Merge branch 'SPR-10534'
* SPR-10534: Add support for DeferredImportSelector Support for @conditional configuration Extend AnnotationMetadata and MethodMetadata
2 parents eb1776e + 7c7fdb0 commit 3126a4c

27 files changed

+1480
-308
lines changed

spring-context/src/main/java/org/springframework/context/annotation/AnnotatedBeanDefinitionReader.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,11 +24,9 @@
2424
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
2525
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2626
import org.springframework.beans.factory.support.BeanNameGenerator;
27-
import org.springframework.core.annotation.AnnotationAttributes;
2827
import org.springframework.core.env.Environment;
2928
import org.springframework.core.env.EnvironmentCapable;
3029
import org.springframework.core.env.StandardEnvironment;
31-
import org.springframework.core.type.AnnotationMetadata;
3230
import org.springframework.util.Assert;
3331

3432
/**
@@ -39,6 +37,7 @@
3937
* @author Juergen Hoeller
4038
* @author Chris Beams
4139
* @author Sam Brannen
40+
* @author Phillip Webb
4241
* @since 3.0
4342
* @see AnnotationConfigApplicationContext#register
4443
*/
@@ -134,12 +133,9 @@ public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>...
134133

135134
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
136135
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
137-
AnnotationMetadata metadata = abd.getMetadata();
138-
if (metadata.isAnnotated(Profile.class.getName())) {
139-
AnnotationAttributes profile = MetadataUtils.attributesFor(metadata, Profile.class);
140-
if (!this.environment.acceptsProfiles(profile.getStringArray("value"))) {
141-
return;
142-
}
136+
if (ConditionalAnnotationHelper.shouldSkip(abd, this.registry,
137+
this.environment, this.beanNameGenerator)) {
138+
return;
143139
}
144140
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
145141
abd.setScope(scopeMetadata.getScopeName());

spring-context/src/main/java/org/springframework/context/annotation/ClassPathBeanDefinitionScanner.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2013 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -52,6 +52,7 @@
5252
* @author Mark Fisher
5353
* @author Juergen Hoeller
5454
* @author Chris Beams
55+
* @author Phillip Webb
5556
* @since 2.5
5657
* @see AnnotationConfigApplicationContext#scan
5758
* @see org.springframework.stereotype.Component
@@ -298,6 +299,10 @@ protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, Bea
298299
* bean definition has been found for the specified name
299300
*/
300301
protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {
302+
if (ConditionalAnnotationHelper.shouldSkip(beanDefinition, getRegistry(),
303+
getEnvironment(), this.beanNameGenerator)) {
304+
return false;
305+
}
301306
if (!this.registry.containsBeanDefinition(beanName)) {
302307
return true;
303308
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2002-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.context.annotation;
18+
19+
import org.jruby.internal.runtime.methods.MethodMethod;
20+
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
21+
import org.springframework.core.type.AnnotatedTypeMetadata;
22+
import org.springframework.core.type.AnnotationMetadata;
23+
24+
/**
25+
* A single {@code condition} that must be {@linkplain #matches matched} in order
26+
* for a component to be registered.
27+
*
28+
* <p>Conditions are checked immediately before a component bean-definition is due to be
29+
* registered and are free to veto registration based on any criteria that can be
30+
* determined at that point.
31+
*
32+
* <p>Conditions must follow the same restrictions as {@link BeanFactoryPostProcessor}
33+
* and take care to never interact with bean instances.
34+
*
35+
* @author Phillip Webb
36+
* @since 4.0
37+
* @see Conditional
38+
* @see ConditionContext
39+
*/
40+
public interface Condition {
41+
42+
/**
43+
* Determine if the condition matches.
44+
* @param context the condition context
45+
* @param metadata meta-data of the {@link AnnotationMetadata class} or
46+
* {@link MethodMethod method} being checked.
47+
* @return {@code true} if the condition matches and the component can be registered
48+
* or {@code false} to veto registration.
49+
*/
50+
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
51+
52+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright 2002-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.context.annotation;
18+
19+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
20+
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
21+
import org.springframework.core.env.Environment;
22+
import org.springframework.core.io.ResourceLoader;
23+
24+
/**
25+
* Context information for use by {@link Condition}s.
26+
*
27+
* @author Phillip Webb
28+
* @since 4.0
29+
*/
30+
public interface ConditionContext {
31+
32+
/**
33+
* Returns the {@link BeanDefinitionRegistry} that will hold the bean definition
34+
* should the condition match.
35+
* @return the registry (never {@code null})
36+
*/
37+
BeanDefinitionRegistry getRegistry();
38+
39+
/**
40+
* Return the {@link Environment} for which the current application is running or
41+
* {@code null} if no environment is available.
42+
* @return the environment or {@code null}
43+
*/
44+
Environment getEnvironment();
45+
46+
/**
47+
* Returns the {@link ConfigurableListableBeanFactory} that will hold the bean
48+
* definition should the condition match. If a
49+
* {@link ConfigurableListableBeanFactory} is unavailable an
50+
* {@link IllegalStateException} will be thrown.
51+
* @return the bean factory
52+
* @throws IllegalStateException if the bean factory could not be obtained
53+
*/
54+
ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
55+
56+
/**
57+
* Returns the {@link ResourceLoader} currently being used or {@code null} if the
58+
* resource loader cannot be obtained.
59+
* @return a resource loader or {@code null}
60+
*/
61+
ResourceLoader getResourceLoader();
62+
63+
/**
64+
* Returns the {@link ClassLoader} that should be used to load additional classes
65+
* or {@code null} if the default classloader should be used.
66+
* @return the classloader or {@code null}
67+
*/
68+
ClassLoader getClassLoader();
69+
70+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2002-2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.context.annotation;
18+
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
23+
24+
/**
25+
* Indicates that a component is is only eligible for registration when all
26+
* {@linkplain #value() specified conditions} match.
27+
*
28+
* <p>A <em>condition</em> is any state that can be determined programmatically
29+
* immediately before the bean is due to be created (see {@link Condition} for details).
30+
*
31+
* <p>The {@code @Conditional} annotation may be used in any of the following ways:
32+
* <ul>
33+
* <li>as a type-level annotation on any class directly or indirectly annotated with
34+
* {@code @Component}, including {@link Configuration @Configuration} classes</li>
35+
* <li>as a meta-annotation, for the purpose of composing custom stereotype
36+
* annotations</li>
37+
* <li>as a method-level annotation on any {@link Bean @Bean} method</li>
38+
* </ul>
39+
*
40+
* <p>If a {@code @Configuration} class is marked with {@code @Conditional}, all of the
41+
* {@code @Bean} methods and {@link Import @Import} annotations associated with that class
42+
* will be subject to the conditions.
43+
*
44+
* @author Phillip Webb
45+
* @since 4.0
46+
* @see Condition
47+
*/
48+
@Retention(RetentionPolicy.RUNTIME)
49+
@Target({ ElementType.TYPE, ElementType.METHOD })
50+
public @interface Conditional {
51+
52+
/**
53+
* All {@link Condition}s that must {@linkplain Condition#matches match} in order for
54+
* the component to be registered.
55+
*/
56+
Class<? extends Condition>[] value();
57+
58+
}

0 commit comments

Comments
 (0)