diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryInitializer.java b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryInitializer.java
new file mode 100644
index 00000000000..30c08739bbb
--- /dev/null
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactoryInitializer.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2002-2024 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.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.beans.factory;
+
+/**
+ * Callback interface for initializing a Spring {@link ListableBeanFactory}
+ * prior to entering the singleton pre-instantiation phase. Can be used to
+ * trigger early initialization of specific beans before regular singletons.
+ *
+ *
Can be programmatically applied to a {@code ListableBeanFactory} instance.
+ * In an {@code ApplicationContext}, beans of type {@code BeanFactoryInitializer}
+ * will be autodetected and automatically applied to the underlying bean factory.
+ *
+ * @author Juergen Hoeller
+ * @since 6.2
+ * @param the bean factory type
+ * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons()
+ */
+public interface BeanFactoryInitializer {
+
+ /**
+ * Initialize the given bean factory.
+ * @param beanFactory the bean factory to bootstrap
+ */
+ void initialize(F beanFactory);
+
+}
diff --git a/spring-context/src/main/java/org/springframework/context/ApplicationContextInitializer.java b/spring-context/src/main/java/org/springframework/context/ApplicationContextInitializer.java
index 42e750fc247..107793410ea 100644
--- a/spring-context/src/main/java/org/springframework/context/ApplicationContextInitializer.java
+++ b/spring-context/src/main/java/org/springframework/context/ApplicationContextInitializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2024 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.
@@ -44,7 +44,7 @@ public interface ApplicationContextInitializer getEnvironment().resolvePlaceholders(strVal));
}
+ // Call BeanFactoryInitializer beans early to allow for initializing specific other beans early.
+ String[] initializerNames = beanFactory.getBeanNamesForType(BeanFactoryInitializer.class, false, false);
+ for (String initializerName : initializerNames) {
+ beanFactory.getBean(initializerName, BeanFactoryInitializer.class).initialize(beanFactory);
+ }
+
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
diff --git a/spring-test/src/main/java/org/springframework/test/context/support/DynamicPropertySourceBeanInitializer.java b/spring-test/src/main/java/org/springframework/test/context/support/DynamicPropertySourceBeanInitializer.java
index ace5ea8ad8e..d30ba11a482 100644
--- a/spring-test/src/main/java/org/springframework/test/context/support/DynamicPropertySourceBeanInitializer.java
+++ b/spring-test/src/main/java/org/springframework/test/context/support/DynamicPropertySourceBeanInitializer.java
@@ -19,55 +19,30 @@ package org.springframework.test.context.support;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.BeanFactoryInitializer;
import org.springframework.beans.factory.ListableBeanFactory;
-import org.springframework.context.weaving.LoadTimeWeaverAware;
-import org.springframework.instrument.classloading.LoadTimeWeaver;
-import org.springframework.lang.Nullable;
import org.springframework.test.context.DynamicPropertySource;
/**
* Internal component which eagerly initializes beans created by {@code @Bean}
* factory methods annotated with {@link DynamicPropertySource @DynamicPropertySource}.
*
- * This class implements {@link LoadTimeWeaverAware} since doing so is
- * currently the only way to have a component eagerly initialized before the
- * {@code ConfigurableListableBeanFactory.preInstantiateSingletons()} phase.
- *
* @author Sam Brannen
* @since 6.2
*/
-class DynamicPropertySourceBeanInitializer implements BeanFactoryAware, InitializingBean, LoadTimeWeaverAware {
+class DynamicPropertySourceBeanInitializer implements BeanFactoryInitializer {
private static final Log logger = LogFactory.getLog(DynamicPropertySourceBeanInitializer.class);
- @Nullable
- private BeanFactory beanFactory;
-
-
- @Override
- public void setBeanFactory(BeanFactory beanFactory) {
- this.beanFactory = beanFactory;
- }
@Override
- public void afterPropertiesSet() {
- if (!(this.beanFactory instanceof ListableBeanFactory lbf)) {
- throw new IllegalStateException("BeanFactory must be set and must be a ListableBeanFactory");
- }
- for (String name : lbf.getBeanNamesForAnnotation(DynamicPropertySource.class)) {
+ public void initialize(ListableBeanFactory beanFactory) {
+ for (String name : beanFactory.getBeanNamesForAnnotation(DynamicPropertySource.class)) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly initializing @DynamicPropertySource bean '%s'".formatted(name));
}
- this.beanFactory.getBean(name);
+ beanFactory.getBean(name);
}
}
- @Override
- public void setLoadTimeWeaver(LoadTimeWeaver loadTimeWeaver) {
- // no-op
- }
-
}