diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java index 166fec179239..fe4121dce00c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/ConfigurableBeanFactory.java @@ -18,6 +18,7 @@ import java.beans.PropertyEditor; import java.security.AccessControlContext; +import java.util.List; import org.springframework.beans.PropertyEditorRegistrar; import org.springframework.beans.PropertyEditorRegistry; @@ -244,6 +245,20 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single */ void addBeanPostProcessor(BeanPostProcessor beanPostProcessor); + /** + * Add new BeanPostProcessors that will get applied to beans created + * by this factory. To be invoked during factory configuration. + *

Note: Post-processors submitted here will be applied in the order of + * registration; any ordering semantics expressed through implementing the + * {@link org.springframework.core.Ordered} interface will be ignored. Note + * that autodetected post-processors (e.g. as beans in an ApplicationContext) + * will always be applied after programmatically registered ones. + * @param beanPostProcessors the post-processors to register + */ + default void addBeanPostProcessors(List beanPostProcessors) { + beanPostProcessors.forEach(this::addBeanPostProcessor); + } + /** * Return the current number of registered BeanPostProcessors, if any. */ diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index ea08a50acd51..21452e76bf3f 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -930,6 +930,23 @@ public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { this.beanPostProcessors.add(beanPostProcessor); } + @Override + public void addBeanPostProcessors(List beanPostProcessors) { + this.beanPostProcessors.removeAll(beanPostProcessors); + + for (BeanPostProcessor beanPostProcessor : beanPostProcessors) { + Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null"); + // Track whether it is instantiation/destruction aware + if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { + this.hasInstantiationAwareBeanPostProcessors = true; + } + if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { + this.hasDestructionAwareBeanPostProcessors = true; + } + } + this.beanPostProcessors.addAll(beanPostProcessors); + } + @Override public int getBeanPostProcessorCount() { return this.beanPostProcessors.size(); diff --git a/spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java b/spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java index 8b9658f53eb6..7c8043535f5d 100644 --- a/spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java +++ b/spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java @@ -220,7 +220,7 @@ else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { // First, register the BeanPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); - registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); + beanFactory.addBeanPostProcessors(priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. List orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); @@ -232,7 +232,7 @@ else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { } } sortPostProcessors(orderedPostProcessors, beanFactory); - registerBeanPostProcessors(beanFactory, orderedPostProcessors); + beanFactory.addBeanPostProcessors(orderedPostProcessors); // Now, register all regular BeanPostProcessors. List nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); @@ -243,11 +243,11 @@ else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { internalPostProcessors.add(pp); } } - registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); + beanFactory.addBeanPostProcessors(nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors. sortPostProcessors(internalPostProcessors, beanFactory); - registerBeanPostProcessors(beanFactory, internalPostProcessors); + beanFactory.addBeanPostProcessors(internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). @@ -287,18 +287,6 @@ private static void invokeBeanFactoryPostProcessors( } } - /** - * Register the given BeanPostProcessor beans. - */ - private static void registerBeanPostProcessors( - ConfigurableListableBeanFactory beanFactory, List postProcessors) { - - for (BeanPostProcessor postProcessor : postProcessors) { - beanFactory.addBeanPostProcessor(postProcessor); - } - } - - /** * BeanPostProcessor that logs an info message when a bean is created during * BeanPostProcessor instantiation, i.e. when a bean is not eligible for