Skip to content

Commit cdf5a11

Browse files
committed
1 parent fa686bb commit cdf5a11

File tree

2 files changed

+64
-8
lines changed

2 files changed

+64
-8
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/ConfigurationPropertiesBeanRegistrar.java

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,18 @@
1616

1717
package org.springframework.boot.context.properties;
1818

19+
import org.springframework.aop.scope.ScopedProxyUtils;
1920
import org.springframework.beans.factory.BeanFactory;
2021
import org.springframework.beans.factory.ListableBeanFactory;
21-
import org.springframework.beans.factory.config.BeanDefinition;
22+
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
23+
import org.springframework.beans.factory.config.BeanDefinitionHolder;
24+
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
2225
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
23-
import org.springframework.beans.factory.support.RootBeanDefinition;
2426
import org.springframework.boot.context.properties.bind.BindMethod;
27+
import org.springframework.context.annotation.AnnotationScopeMetadataResolver;
28+
import org.springframework.context.annotation.ScopeMetadata;
29+
import org.springframework.context.annotation.ScopeMetadataResolver;
30+
import org.springframework.context.annotation.ScopedProxyMode;
2531
import org.springframework.core.annotation.MergedAnnotation;
2632
import org.springframework.core.annotation.MergedAnnotations;
2733
import org.springframework.core.annotation.MergedAnnotations.SearchStrategy;
@@ -42,6 +48,8 @@ final class ConfigurationPropertiesBeanRegistrar {
4248

4349
private final BeanFactory beanFactory;
4450

51+
private static final ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
52+
4553
ConfigurationPropertiesBeanRegistrar(BeanDefinitionRegistry registry) {
4654
this.registry = registry;
4755
this.beanFactory = (BeanFactory) this.registry;
@@ -75,17 +83,25 @@ private void registerBeanDefinition(String beanName, Class<?> type,
7583
MergedAnnotation<ConfigurationProperties> annotation) {
7684
Assert.state(annotation.isPresent(), () -> "No " + ConfigurationProperties.class.getSimpleName()
7785
+ " annotation found on '" + type.getName() + "'.");
78-
this.registry.registerBeanDefinition(beanName, createBeanDefinition(beanName, type));
86+
BeanDefinitionReaderUtils.registerBeanDefinition(createBeanDefinition(beanName, type), this.registry);
7987
}
8088

81-
private BeanDefinition createBeanDefinition(String beanName, Class<?> type) {
89+
private BeanDefinitionHolder createBeanDefinition(String beanName, Class<?> type) {
8290
BindMethod bindMethod = ConfigurationPropertiesBean.deduceBindMethod(type);
83-
RootBeanDefinition definition = new RootBeanDefinition(type);
91+
AnnotatedGenericBeanDefinition definition = new AnnotatedGenericBeanDefinition(type);
8492
BindMethodAttribute.set(definition, bindMethod);
8593
if (bindMethod == BindMethod.VALUE_OBJECT) {
8694
definition.setInstanceSupplier(() -> ConstructorBound.from(this.beanFactory, beanName, type));
8795
}
88-
return definition;
96+
ScopeMetadata metadata = scopeMetadataResolver.resolveScopeMetadata(definition);
97+
definition.setScope(metadata.getScopeName());
98+
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(definition, beanName);
99+
ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
100+
if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
101+
return definitionHolder;
102+
}
103+
boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
104+
return ScopedProxyUtils.createScopedProxy(definitionHolder, this.registry, proxyTargetClass);
89105
}
90106

91107
}

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/ConfigurationPropertiesBeanRegistrarTests.java

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@
2020

2121
import org.junit.jupiter.api.Test;
2222

23+
import org.springframework.aop.scope.ScopedProxyFactoryBean;
24+
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
2325
import org.springframework.beans.factory.config.BeanDefinition;
2426
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2527
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
2628
import org.springframework.beans.factory.support.GenericBeanDefinition;
27-
import org.springframework.beans.factory.support.RootBeanDefinition;
2829
import org.springframework.boot.context.properties.bind.BindMethod;
30+
import org.springframework.context.annotation.Scope;
31+
import org.springframework.context.annotation.ScopedProxyMode;
2932

3033
import static org.assertj.core.api.Assertions.assertThat;
3134
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
@@ -44,6 +47,31 @@ class ConfigurationPropertiesBeanRegistrarTests {
4447
private final ConfigurationPropertiesBeanRegistrar registrar = new ConfigurationPropertiesBeanRegistrar(
4548
this.registry);
4649

50+
@Test
51+
void registerScopedBeanDefinition() {
52+
String beanName = "scopedbeancp-" + ScopedBeanConfigurationProperties.class.getName();
53+
this.registrar.register(ScopedBeanConfigurationProperties.class);
54+
BeanDefinition beanDefinition = this.registry.getBeanDefinition(beanName);
55+
assertThat(beanDefinition).isNotNull();
56+
assertThat(beanDefinition.getBeanClassName()).isEqualTo(ScopedBeanConfigurationProperties.class.getName());
57+
assertThat(beanDefinition.getScope()).isEqualTo(BeanDefinition.SCOPE_PROTOTYPE);
58+
}
59+
60+
@Test
61+
void registerScopedBeanDefinitionWithProxyMode() {
62+
String beanName = "scopedbeancp-" + ProxyScopedBeanConfigurationProperties.class.getName();
63+
this.registrar.register(ProxyScopedBeanConfigurationProperties.class);
64+
BeanDefinition proxiedBeanDefinition = this.registry.getBeanDefinition(beanName);
65+
assertThat(proxiedBeanDefinition).isNotNull();
66+
assertThat(proxiedBeanDefinition.getBeanClassName()).isEqualTo(ScopedProxyFactoryBean.class.getName());
67+
String targetBeanName = (String) proxiedBeanDefinition.getPropertyValues().get("targetBeanName");
68+
assertThat(targetBeanName).isNotNull();
69+
BeanDefinition beanDefinition = this.registry.getBeanDefinition(targetBeanName);
70+
assertThat(beanDefinition).isNotNull();
71+
assertThat(beanDefinition.getBeanClassName()).isEqualTo(ProxyScopedBeanConfigurationProperties.class.getName());
72+
assertThat(beanDefinition.getScope()).isEqualTo(BeanDefinition.SCOPE_PROTOTYPE);
73+
}
74+
4775
@Test
4876
void registerWhenNotAlreadyRegisteredAddBeanDefinition() {
4977
String beanName = "beancp-" + BeanConfigurationProperties.class.getName();
@@ -88,7 +116,7 @@ void registerWhenNotValueObjectRegistersRootBeanDefinitionWithJavaBeanBindMethod
88116

89117
private Consumer<BeanDefinition> configurationPropertiesBeanDefinition(BindMethod bindMethod) {
90118
return (definition) -> {
91-
assertThat(definition).isExactlyInstanceOf(RootBeanDefinition.class);
119+
assertThat(definition).isExactlyInstanceOf(AnnotatedGenericBeanDefinition.class);
92120
assertThat(definition.hasAttribute(BindMethod.class.getName())).isTrue();
93121
assertThat(definition.getAttribute(BindMethod.class.getName())).isEqualTo(bindMethod);
94122
};
@@ -99,6 +127,18 @@ static class BeanConfigurationProperties {
99127

100128
}
101129

130+
@ConfigurationProperties(prefix = "scopedbeancp")
131+
@Scope("prototype")
132+
static class ScopedBeanConfigurationProperties {
133+
134+
}
135+
136+
@ConfigurationProperties(prefix = "scopedbeancp")
137+
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS, value = "prototype")
138+
static class ProxyScopedBeanConfigurationProperties {
139+
140+
}
141+
102142
static class NoAnnotationConfigurationProperties {
103143

104144
}

0 commit comments

Comments
 (0)