Skip to content

Commit c1022e7

Browse files
Dave Syerwilkinsona
authored andcommitted
Add CachingMetadataReaderFactoryPostProcessor earlier in context lifecyle
An initializer that adds a BeanDefinitionRegistryPostProcessor which in turn adds bean definitions has to be very careful to run early. Otherwise, other initializers that want to influence the bean definitions added never get a chance. Closes gh-14907
1 parent eafee8b commit c1022e7

File tree

2 files changed

+97
-2
lines changed

2 files changed

+97
-2
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/SharedMetadataReaderFactoryContextInitializer.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
* @author Phillip Webb
4747
* @since 1.4.0
4848
*/
49-
class SharedMetadataReaderFactoryContextInitializer
50-
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
49+
class SharedMetadataReaderFactoryContextInitializer implements
50+
ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
5151

5252
public static final String BEAN_NAME = "org.springframework.boot.autoconfigure."
5353
+ "internalCachingMetadataReaderFactory";
@@ -58,6 +58,12 @@ public void initialize(ConfigurableApplicationContext applicationContext) {
5858
new CachingMetadataReaderFactoryPostProcessor());
5959
}
6060

61+
@Override
62+
public int getOrder() {
63+
// Should happen before other BeanDefinitionRegistryPostProcessors are added
64+
return 0;
65+
}
66+
6167
/**
6268
* {@link BeanDefinitionRegistryPostProcessor} to register the
6369
* {@link CachingMetadataReaderFactory} and configure the
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright 2016-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.boot.autoconfigure;
17+
18+
import java.util.List;
19+
20+
import org.junit.Test;
21+
22+
import org.springframework.beans.BeansException;
23+
import org.springframework.beans.factory.config.BeanDefinition;
24+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
25+
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
26+
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
27+
import org.springframework.boot.SpringApplication;
28+
import org.springframework.boot.WebApplicationType;
29+
import org.springframework.context.ApplicationContextInitializer;
30+
import org.springframework.context.support.GenericApplicationContext;
31+
import org.springframework.test.util.ReflectionTestUtils;
32+
33+
import static org.assertj.core.api.Assertions.assertThat;
34+
35+
/**
36+
* @author Dave Syer
37+
*
38+
*/
39+
public class SharedMetadataReaderFactoryContextInitializerTests {
40+
41+
@Test
42+
public void checkOrderOfInitializer() {
43+
SpringApplication application = new SpringApplication(TestConfig.class);
44+
application.setWebApplicationType(WebApplicationType.NONE);
45+
@SuppressWarnings("unchecked")
46+
List<ApplicationContextInitializer<?>> initializers = (List<ApplicationContextInitializer<?>>) ReflectionTestUtils
47+
.getField(application, "initializers");
48+
// Simulate what would happen if an initializer was added using spring.factories
49+
// and happened to be loaded first
50+
initializers.add(0, new Initializer());
51+
GenericApplicationContext context = (GenericApplicationContext) application.run();
52+
BeanDefinition definition = context.getBeanDefinition(
53+
SharedMetadataReaderFactoryContextInitializer.BEAN_NAME);
54+
assertThat(definition.getAttribute("seen")).isEqualTo(true);
55+
}
56+
57+
protected static class TestConfig {
58+
59+
}
60+
61+
static class Initializer
62+
implements ApplicationContextInitializer<GenericApplicationContext> {
63+
64+
@Override
65+
public void initialize(GenericApplicationContext applicationContext) {
66+
applicationContext.addBeanFactoryPostProcessor(new PostProcessor());
67+
}
68+
69+
}
70+
71+
static class PostProcessor implements BeanDefinitionRegistryPostProcessor {
72+
73+
@Override
74+
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
75+
throws BeansException {
76+
}
77+
78+
@Override
79+
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
80+
throws BeansException {
81+
for (String name : registry.getBeanDefinitionNames()) {
82+
BeanDefinition definition = registry.getBeanDefinition(name);
83+
definition.setAttribute("seen", true);
84+
}
85+
}
86+
87+
}
88+
89+
}

0 commit comments

Comments
 (0)