Skip to content

Commit 7610210

Browse files
committed
Consistently sort BeanDefinitionRegistryPostProcessors
Issue: SPR-16043 (cherry picked from commit ad4c8e7)
1 parent a4803d8 commit 7610210

File tree

2 files changed

+77
-35
lines changed

2 files changed

+77
-35
lines changed

spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,14 @@ public static void invokeBeanFactoryPostProcessors(
5858
if (beanFactory instanceof BeanDefinitionRegistry) {
5959
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
6060
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
61-
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
62-
new LinkedList<BeanDefinitionRegistryPostProcessor>();
61+
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
6362

6463
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
6564
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
66-
BeanDefinitionRegistryPostProcessor registryPostProcessor =
65+
BeanDefinitionRegistryPostProcessor registryProcessor =
6766
(BeanDefinitionRegistryPostProcessor) postProcessor;
68-
registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
69-
registryPostProcessors.add(registryPostProcessor);
67+
registryProcessor.postProcessBeanDefinitionRegistry(registry);
68+
registryProcessors.add(registryProcessor);
7069
}
7170
else {
7271
regularPostProcessors.add(postProcessor);
@@ -77,33 +76,34 @@ public static void invokeBeanFactoryPostProcessors(
7776
// uninitialized to let the bean factory post-processors apply to them!
7877
// Separate between BeanDefinitionRegistryPostProcessors that implement
7978
// PriorityOrdered, Ordered, and the rest.
80-
String[] postProcessorNames =
81-
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
79+
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
8280

8381
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
84-
List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
82+
String[] postProcessorNames =
83+
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
8584
for (String ppName : postProcessorNames) {
8685
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
87-
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
86+
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
8887
processedBeans.add(ppName);
8988
}
9089
}
91-
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
92-
registryPostProcessors.addAll(priorityOrderedPostProcessors);
93-
invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
90+
sortPostProcessors(currentRegistryProcessors, beanFactory);
91+
registryProcessors.addAll(currentRegistryProcessors);
92+
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
93+
currentRegistryProcessors.clear();
9494

9595
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
9696
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
97-
List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
9897
for (String ppName : postProcessorNames) {
9998
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
100-
orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
99+
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
101100
processedBeans.add(ppName);
102101
}
103102
}
104-
sortPostProcessors(beanFactory, orderedPostProcessors);
105-
registryPostProcessors.addAll(orderedPostProcessors);
106-
invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
103+
sortPostProcessors(currentRegistryProcessors, beanFactory);
104+
registryProcessors.addAll(currentRegistryProcessors);
105+
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
106+
currentRegistryProcessors.clear();
107107

108108
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
109109
boolean reiterate = true;
@@ -112,17 +112,19 @@ public static void invokeBeanFactoryPostProcessors(
112112
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
113113
for (String ppName : postProcessorNames) {
114114
if (!processedBeans.contains(ppName)) {
115-
BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
116-
registryPostProcessors.add(pp);
115+
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
117116
processedBeans.add(ppName);
118-
pp.postProcessBeanDefinitionRegistry(registry);
119117
reiterate = true;
120118
}
121119
}
120+
sortPostProcessors(currentRegistryProcessors, beanFactory);
121+
registryProcessors.addAll(currentRegistryProcessors);
122+
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
123+
currentRegistryProcessors.clear();
122124
}
123125

124126
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
125-
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
127+
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
126128
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
127129
}
128130

@@ -157,15 +159,15 @@ else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
157159
}
158160

159161
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
160-
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
162+
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
161163
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
162164

163165
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
164166
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
165167
for (String postProcessorName : orderedPostProcessorNames) {
166168
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
167169
}
168-
sortPostProcessors(beanFactory, orderedPostProcessors);
170+
sortPostProcessors(orderedPostProcessors, beanFactory);
169171
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
170172

171173
// Finally, invoke all other BeanFactoryPostProcessors.
@@ -214,7 +216,7 @@ else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
214216
}
215217

216218
// First, register the BeanPostProcessors that implement PriorityOrdered.
217-
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
219+
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
218220
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
219221

220222
// Next, register the BeanPostProcessors that implement Ordered.
@@ -226,7 +228,7 @@ else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
226228
internalPostProcessors.add(pp);
227229
}
228230
}
229-
sortPostProcessors(beanFactory, orderedPostProcessors);
231+
sortPostProcessors(orderedPostProcessors, beanFactory);
230232
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
231233

232234
// Now, register all regular BeanPostProcessors.
@@ -241,15 +243,15 @@ else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
241243
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
242244

243245
// Finally, re-register all internal BeanPostProcessors.
244-
sortPostProcessors(beanFactory, internalPostProcessors);
246+
sortPostProcessors(internalPostProcessors, beanFactory);
245247
registerBeanPostProcessors(beanFactory, internalPostProcessors);
246248

247249
// Re-register post-processor for detecting inner beans as ApplicationListeners,
248250
// moving it to the end of the processor chain (for picking up proxies etc).
249251
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
250252
}
251253

252-
private static void sortPostProcessors(ConfigurableListableBeanFactory beanFactory, List<?> postProcessors) {
254+
private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
253255
Comparator<Object> comparatorToUse = null;
254256
if (beanFactory instanceof DefaultListableBeanFactory) {
255257
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();

spring-context/src/test/java/org/springframework/context/support/BeanFactoryPostProcessorTests.java

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 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.
@@ -31,6 +31,7 @@
3131
import org.springframework.context.ApplicationEvent;
3232
import org.springframework.context.ApplicationListener;
3333
import org.springframework.context.event.ContextRefreshedEvent;
34+
import org.springframework.core.Ordered;
3435
import org.springframework.core.PriorityOrdered;
3536
import org.springframework.tests.sample.beans.TestBean;
3637
import org.springframework.util.Assert;
@@ -101,26 +102,40 @@ public void testBeanFactoryPostProcessorNotExecutedByBeanFactory() {
101102
}
102103

103104
@Test
104-
public void testBeanDefinitionRegistryPostProcessor() throws Exception {
105+
public void testBeanDefinitionRegistryPostProcessor() {
105106
StaticApplicationContext ac = new StaticApplicationContext();
106107
ac.registerSingleton("tb1", TestBean.class);
107108
ac.registerSingleton("tb2", TestBean.class);
109+
ac.addBeanFactoryPostProcessor(new PrioritizedBeanDefinitionRegistryPostProcessor());
108110
TestBeanDefinitionRegistryPostProcessor bdrpp = new TestBeanDefinitionRegistryPostProcessor();
109111
ac.addBeanFactoryPostProcessor(bdrpp);
110112
assertFalse(bdrpp.wasCalled);
111113
ac.refresh();
112114
assertTrue(bdrpp.wasCalled);
113-
assertTrue(ac.getBean(TestBeanFactoryPostProcessor.class).wasCalled);
115+
assertTrue(ac.getBean("bfpp1", TestBeanFactoryPostProcessor.class).wasCalled);
116+
assertTrue(ac.getBean("bfpp2", TestBeanFactoryPostProcessor.class).wasCalled);
114117
}
115118

116119
@Test
117-
public void testBeanDefinitionRegistryPostProcessorRegisteringAnother() throws Exception {
120+
public void testBeanDefinitionRegistryPostProcessorRegisteringAnother() {
118121
StaticApplicationContext ac = new StaticApplicationContext();
119122
ac.registerSingleton("tb1", TestBean.class);
120123
ac.registerSingleton("tb2", TestBean.class);
121-
ac.registerBeanDefinition("bdrpp2", new RootBeanDefinition(TestBeanDefinitionRegistryPostProcessor2.class));
124+
ac.registerBeanDefinition("bdrpp2", new RootBeanDefinition(OuterBeanDefinitionRegistryPostProcessor.class));
122125
ac.refresh();
123-
assertTrue(ac.getBean(TestBeanFactoryPostProcessor.class).wasCalled);
126+
assertTrue(ac.getBean("bfpp1", TestBeanFactoryPostProcessor.class).wasCalled);
127+
assertTrue(ac.getBean("bfpp2", TestBeanFactoryPostProcessor.class).wasCalled);
128+
}
129+
130+
@Test
131+
public void testPrioritizedBeanDefinitionRegistryPostProcessorRegisteringAnother() {
132+
StaticApplicationContext ac = new StaticApplicationContext();
133+
ac.registerSingleton("tb1", TestBean.class);
134+
ac.registerSingleton("tb2", TestBean.class);
135+
ac.registerBeanDefinition("bdrpp2", new RootBeanDefinition(PrioritizedOuterBeanDefinitionRegistryPostProcessor.class));
136+
ac.refresh();
137+
assertTrue(ac.getBean("bfpp1", TestBeanFactoryPostProcessor.class).wasCalled);
138+
assertTrue(ac.getBean("bfpp2", TestBeanFactoryPostProcessor.class).wasCalled);
124139
}
125140

126141
@Test
@@ -159,13 +174,32 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
159174
}
160175

161176

177+
public static class PrioritizedBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, Ordered {
178+
179+
@Override
180+
public int getOrder() {
181+
return Ordered.HIGHEST_PRECEDENCE;
182+
}
183+
184+
@Override
185+
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
186+
registry.registerBeanDefinition("bfpp1", new RootBeanDefinition(TestBeanFactoryPostProcessor.class));
187+
}
188+
189+
@Override
190+
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
191+
}
192+
}
193+
194+
162195
public static class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
163196

164197
public boolean wasCalled;
165198

166199
@Override
167200
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
168-
registry.registerBeanDefinition("bfpp", new RootBeanDefinition(TestBeanFactoryPostProcessor.class));
201+
assertTrue(registry.containsBeanDefinition("bfpp1"));
202+
registry.registerBeanDefinition("bfpp2", new RootBeanDefinition(TestBeanFactoryPostProcessor.class));
169203
}
170204

171205
@Override
@@ -175,16 +209,22 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
175209
}
176210

177211

178-
public static class TestBeanDefinitionRegistryPostProcessor2 implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
212+
public static class OuterBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
179213

180214
@Override
181215
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
182216
registry.registerBeanDefinition("anotherpp", new RootBeanDefinition(TestBeanDefinitionRegistryPostProcessor.class));
217+
registry.registerBeanDefinition("ppp", new RootBeanDefinition(PrioritizedBeanDefinitionRegistryPostProcessor.class));
183218
}
184219

185220
@Override
186221
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
187222
}
223+
}
224+
225+
226+
public static class PrioritizedOuterBeanDefinitionRegistryPostProcessor extends OuterBeanDefinitionRegistryPostProcessor
227+
implements PriorityOrdered {
188228

189229
@Override
190230
public int getOrder() {

0 commit comments

Comments
 (0)