Skip to content

Commit ae79c60

Browse files
mhalbritterphilwebb
authored andcommitted
Remove instance suppliers in bean definitions
Remove instance suppliers in bean definitions and depend instead on reflection. This allows the AOT engine to correctly process the definitions. Fixes gh-33763
1 parent 71efc55 commit ae79c60

File tree

4 files changed

+39
-51
lines changed

4 files changed

+39
-51
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfiguration.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 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.
@@ -16,8 +16,6 @@
1616

1717
package org.springframework.boot.autoconfigure.web.reactive;
1818

19-
import java.util.function.Supplier;
20-
2119
import org.springframework.beans.BeansException;
2220
import org.springframework.beans.factory.BeanFactory;
2321
import org.springframework.beans.factory.BeanFactoryAware;
@@ -102,14 +100,13 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
102100
return;
103101
}
104102
registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor",
105-
WebServerFactoryCustomizerBeanPostProcessor.class,
106-
WebServerFactoryCustomizerBeanPostProcessor::new);
103+
WebServerFactoryCustomizerBeanPostProcessor.class);
107104
}
108105

109106
private <T> void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name,
110-
Class<T> beanClass, Supplier<T> instanceSupplier) {
107+
Class<T> beanClass) {
111108
if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {
112-
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass, instanceSupplier);
109+
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
113110
beanDefinition.setSynthetic(true);
114111
registry.registerBeanDefinition(name, beanDefinition);
115112
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfiguration.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 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.
@@ -16,8 +16,6 @@
1616

1717
package org.springframework.boot.autoconfigure.web.servlet;
1818

19-
import java.util.function.Supplier;
20-
2119
import jakarta.servlet.DispatcherType;
2220
import jakarta.servlet.ServletRequest;
2321

@@ -139,16 +137,15 @@ public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
139137
return;
140138
}
141139
registerSyntheticBeanIfMissing(registry, "webServerFactoryCustomizerBeanPostProcessor",
142-
WebServerFactoryCustomizerBeanPostProcessor.class,
143-
WebServerFactoryCustomizerBeanPostProcessor::new);
140+
WebServerFactoryCustomizerBeanPostProcessor.class);
144141
registerSyntheticBeanIfMissing(registry, "errorPageRegistrarBeanPostProcessor",
145-
ErrorPageRegistrarBeanPostProcessor.class, ErrorPageRegistrarBeanPostProcessor::new);
142+
ErrorPageRegistrarBeanPostProcessor.class);
146143
}
147144

148145
private <T> void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name,
149-
Class<T> beanClass, Supplier<T> instanceSupplier) {
146+
Class<T> beanClass) {
150147
if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {
151-
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass, instanceSupplier);
148+
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
152149
beanDefinition.setSynthetic(true);
153150
registry.registerBeanDefinition(name, beanDefinition);
154151
}

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 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.
@@ -81,8 +81,7 @@ public static BoundConfigurationProperties get(ApplicationContext context) {
8181
static void register(BeanDefinitionRegistry registry) {
8282
Assert.notNull(registry, "Registry must not be null");
8383
if (!registry.containsBeanDefinition(BEAN_NAME)) {
84-
BeanDefinition definition = BeanDefinitionBuilder
85-
.genericBeanDefinition(BoundConfigurationProperties.class, BoundConfigurationProperties::new)
84+
BeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(BoundConfigurationProperties.class)
8685
.getBeanDefinition();
8786
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
8887
registry.registerBeanDefinition(BEAN_NAME, definition);

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

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2022 the original author or authors.
2+
* Copyright 2012-2023 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.
@@ -50,6 +50,7 @@
5050
import org.springframework.core.annotation.MergedAnnotations;
5151
import org.springframework.core.convert.ConversionService;
5252
import org.springframework.core.env.PropertySources;
53+
import org.springframework.util.Assert;
5354
import org.springframework.validation.Validator;
5455
import org.springframework.validation.annotation.Validated;
5556

@@ -64,8 +65,6 @@ class ConfigurationPropertiesBinder {
6465

6566
private static final String BEAN_NAME = "org.springframework.boot.context.internalConfigurationPropertiesBinder";
6667

67-
private static final String FACTORY_BEAN_NAME = "org.springframework.boot.context.internalConfigurationPropertiesBinderFactory";
68-
6968
private static final String VALIDATOR_BEAN_NAME = EnableConfigurationProperties.VALIDATOR_BEAN_NAME;
7069

7170
private final ApplicationContext applicationContext;
@@ -189,18 +188,9 @@ private Consumer<PropertyEditorRegistry> getPropertyEditorInitializer() {
189188
}
190189

191190
static void register(BeanDefinitionRegistry registry) {
192-
if (!registry.containsBeanDefinition(FACTORY_BEAN_NAME)) {
193-
BeanDefinition definition = BeanDefinitionBuilder
194-
.rootBeanDefinition(ConfigurationPropertiesBinder.Factory.class).getBeanDefinition();
195-
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
196-
registry.registerBeanDefinition(ConfigurationPropertiesBinder.FACTORY_BEAN_NAME, definition);
197-
}
198191
if (!registry.containsBeanDefinition(BEAN_NAME)) {
199192
BeanDefinition definition = BeanDefinitionBuilder
200-
.rootBeanDefinition(ConfigurationPropertiesBinder.class,
201-
() -> ((BeanFactory) registry)
202-
.getBean(FACTORY_BEAN_NAME, ConfigurationPropertiesBinder.Factory.class).create())
203-
.getBeanDefinition();
193+
.rootBeanDefinition(ConfigurationPropertiesBinderFactory.class).getBeanDefinition();
204194
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
205195
registry.registerBeanDefinition(ConfigurationPropertiesBinder.BEAN_NAME, definition);
206196
}
@@ -211,44 +201,49 @@ static ConfigurationPropertiesBinder get(BeanFactory beanFactory) {
211201
}
212202

213203
/**
214-
* Factory bean used to create the {@link ConfigurationPropertiesBinder}. The bean
215-
* needs to be {@link ApplicationContextAware} since we can't directly inject an
216-
* {@link ApplicationContext} into the constructor without causing eager
217-
* {@link FactoryBean} initialization.
204+
* {@link BindHandler} to deal with
205+
* {@link ConfigurationProperties @ConfigurationProperties} concerns.
218206
*/
219-
static class Factory implements ApplicationContextAware {
207+
private static class ConfigurationPropertiesBindHandler extends AbstractBindHandler {
220208

221-
private ApplicationContext applicationContext;
209+
ConfigurationPropertiesBindHandler(BindHandler handler) {
210+
super(handler);
211+
}
222212

223213
@Override
224-
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
225-
this.applicationContext = applicationContext;
214+
public <T> Bindable<T> onStart(ConfigurationPropertyName name, Bindable<T> target, BindContext context) {
215+
return isConfigurationProperties(target.getType().resolve())
216+
? target.withBindRestrictions(BindRestriction.NO_DIRECT_PROPERTY) : target;
226217
}
227218

228-
ConfigurationPropertiesBinder create() {
229-
return new ConfigurationPropertiesBinder(this.applicationContext);
219+
private boolean isConfigurationProperties(Class<?> target) {
220+
return target != null && MergedAnnotations.from(target).isPresent(ConfigurationProperties.class);
230221
}
231222

232223
}
233224

234225
/**
235-
* {@link BindHandler} to deal with
236-
* {@link ConfigurationProperties @ConfigurationProperties} concerns.
226+
* {@link FactoryBean} to create the {@link ConfigurationPropertiesBinder}.
237227
*/
238-
private static class ConfigurationPropertiesBindHandler extends AbstractBindHandler {
228+
static class ConfigurationPropertiesBinderFactory
229+
implements FactoryBean<ConfigurationPropertiesBinder>, ApplicationContextAware {
239230

240-
ConfigurationPropertiesBindHandler(BindHandler handler) {
241-
super(handler);
231+
private ConfigurationPropertiesBinder binder;
232+
233+
@Override
234+
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
235+
this.binder = (this.binder != null) ? this.binder : new ConfigurationPropertiesBinder(applicationContext);
242236
}
243237

244238
@Override
245-
public <T> Bindable<T> onStart(ConfigurationPropertyName name, Bindable<T> target, BindContext context) {
246-
return isConfigurationProperties(target.getType().resolve())
247-
? target.withBindRestrictions(BindRestriction.NO_DIRECT_PROPERTY) : target;
239+
public Class<?> getObjectType() {
240+
return ConfigurationPropertiesBinder.class;
248241
}
249242

250-
private boolean isConfigurationProperties(Class<?> target) {
251-
return target != null && MergedAnnotations.from(target).isPresent(ConfigurationProperties.class);
243+
@Override
244+
public ConfigurationPropertiesBinder getObject() throws Exception {
245+
Assert.state(this.binder != null, "Binder was not created due to missing setApplicationContext call");
246+
return this.binder;
252247
}
253248

254249
}

0 commit comments

Comments
 (0)