Skip to content

Commit fd8935b

Browse files
committed
SPR-5682:
* polishing for ConfigurationClassApplicationContext & tests * added ConfigurationClassWebApplicationContext & tests * next: refactoring out duplications between ConfigurationClassApplicationContext & ConfigurationClassWebApplicationContext
1 parent 772a74a commit fd8935b

File tree

5 files changed

+275
-50
lines changed

5 files changed

+275
-50
lines changed

org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassApplicationContext.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ public class ConfigurationClassApplicationContext extends AbstractRefreshableApp
5353
private final Set<Class<?>> configClasses = new LinkedHashSet<Class<?>>();
5454

5555
/**
56-
* Create a new {@link ConfigurationClassApplicationContext}, loading bean
56+
* Create a new {@link ConfigurationClassApplicationContext}, loading bean
5757
* definitions from the given {@literal configClasses} and automatically
5858
* refreshing the context. <p>Note: if zero classes are specified, the
5959
* context will <b>not</b> be refreshed automatically, assuming that
6060
* the user will subsequently call {@link #addConfigurationClass(Class)}
6161
* and then manually refresh.
62-
*
62+
*
6363
* @param configClasses zero or more {@link Configuration} classes
6464
* @see #addConfigurationClass(Class)
6565
* @see #refresh()
@@ -68,14 +68,14 @@ public ConfigurationClassApplicationContext(Class<?>... configClasses) {
6868
if (configClasses.length == 0) {
6969
return;
7070
}
71-
71+
7272
for (Class<?> configClass : configClasses) {
7373
addConfigurationClass(configClass);
7474
}
75-
75+
7676
this.refresh();
7777
}
78-
78+
7979
/**
8080
* Add a {@link Configuration} class to be processed. Allows for programmatically
8181
* building a {@link ConfigurationClassApplicationContext}. Note that
@@ -99,36 +99,36 @@ public void addConfigurationClass(Class<?> configClass) {
9999
* class specified. Enables the default set of annotation configuration post
100100
* processors, such that {@literal @Autowired}, {@literal @Required}, and associated
101101
* annotations can be used within Configuration classes.
102-
*
102+
*
103103
* <p>Configuration class bean definitions are registered with generated bean definition names.
104-
*
104+
*
105105
* @see AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)
106106
* @see ConfigurationClassPostProcessor
107107
*/
108108
@Override
109109
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
110110
throws IOException, BeansException {
111-
111+
112112
// @Autowired and friends must be enabled by default when processing @Configuration classes
113113
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
114-
114+
115115
for (Class<?> configClass : configClasses) {
116116
AbstractBeanDefinition def = BeanDefinitionBuilder.rootBeanDefinition(configClass).getBeanDefinition();
117-
117+
118118
String name = AnnotationUtils.findAnnotation(configClass, Configuration.class).value();
119119
if (!StringUtils.hasLength(name)) {
120120
name = new DefaultBeanNameGenerator().generateBeanName(def, beanFactory);
121121
}
122122

123123
beanFactory.registerBeanDefinition(name, def);
124124
}
125-
125+
126126
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
127127
}
128128

129129
/**
130130
* Return the bean instance that matches the given object type.
131-
*
131+
*
132132
* @param <T>
133133
* @param requiredType type the bean must match; can be an interface or superclass.
134134
* {@literal null} is disallowed.
@@ -141,9 +141,9 @@ protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
141141
@SuppressWarnings("unchecked")
142142
public <T> T getBean(Class<T> requiredType) {
143143
Assert.notNull(requiredType, "requiredType may not be null");
144-
144+
145145
Map<String, ?> beansOfType = this.getBeansOfType(requiredType);
146-
146+
147147
switch (beansOfType.size()) {
148148
case 0:
149149
throw new NoSuchBeanDefinitionException(requiredType);

org.springframework.context/src/main/java/org/springframework/context/support/AbstractRefreshableApplicationContext.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
/**
3030
* Base class for {@link org.springframework.context.ApplicationContext}
31-
* implementations which are supposed to support multiple refreshs,
31+
* implementations which are supposed to support multiple calls to {@literal refresh},
3232
* creating a new internal bean factory instance every time.
3333
* Typically (but not necessarily), such a context will be driven by
3434
* a set of config locations to load bean definitions from.
@@ -48,7 +48,9 @@
4848
* <p>Concrete standalone subclasses of this base class, reading in a
4949
* specific bean definition format, are {@link ClassPathXmlApplicationContext}
5050
* and {@link FileSystemXmlApplicationContext}, which both derive from the
51-
* common {@link AbstractXmlApplicationContext} base class.
51+
* common {@link AbstractXmlApplicationContext} base class;
52+
* {@link org.springframework.context.annotation.ConfigurationClassApplicationContext}
53+
* supports {@literal @Configuration}-annotated classes as a source of bean definitions.
5254
*
5355
* @author Juergen Hoeller
5456
* @since 1.1.3
@@ -58,6 +60,7 @@
5860
* @see AbstractXmlApplicationContext
5961
* @see ClassPathXmlApplicationContext
6062
* @see FileSystemXmlApplicationContext
63+
* @see org.springframework.context.annotation.ConfigurationClassApplicationContext
6164
*/
6265
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
6366

@@ -130,7 +133,7 @@ protected final void refreshBeanFactory() throws BeansException {
130133
}
131134
}
132135
catch (IOException ex) {
133-
throw new ApplicationContextException("I/O error parsing XML document for " + getDisplayName(), ex);
136+
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
134137
}
135138
}
136139

org.springframework.context/src/test/java/org/springframework/context/annotation/ConfigurationClassApplicationContextTests.java

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,28 @@
2020

2121
import static org.hamcrest.CoreMatchers.*;
2222
import static org.junit.matchers.JUnitMatchers.*;
23-
import static org.junit.Assert.assertNotNull;
24-
import static org.junit.Assert.assertThat;
25-
import static org.junit.Assert.fail;
23+
import static org.junit.Assert.*;
2624

2725
import org.junit.Test;
2826
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
2927
import org.springframework.beans.factory.annotation.Autowired;
3028

3129
public class ConfigurationClassApplicationContextTests {
32-
30+
3331
@Test(expected=IllegalStateException.class)
3432
public void emptyConstructorRequiresManualRefresh() {
3533
ConfigurationClassApplicationContext context = new ConfigurationClassApplicationContext();
3634
context.getBean("foo");
3735
}
38-
36+
3937
@Test
4038
public void classesMissingConfigurationAnnotationAddedToContextAreDisallowed() {
4139
ConfigurationClassApplicationContext ctx =
4240
new ConfigurationClassApplicationContext(Config.class);
43-
41+
4442
// should be fine
4543
ctx.addConfigurationClass(ConfigWithCustomName.class);
46-
44+
4745
// should cause immediate failure (no refresh necessary)
4846
try {
4947
ctx.addConfigurationClass(ConfigMissingAnnotation.class);
@@ -54,19 +52,18 @@ public void classesMissingConfigurationAnnotationAddedToContextAreDisallowed() {
5452
"is not annotated with @Configuration"));
5553
}
5654
}
57-
55+
5856
@Test(expected=IllegalArgumentException.class)
5957
public void classesMissingConfigurationAnnotationSuppliedToConstructorAreDisallowed() {
6058
new ConfigurationClassApplicationContext(ConfigMissingAnnotation.class);
6159
}
62-
63-
60+
6461
@Test(expected=IllegalArgumentException.class)
6562
public void nullGetBeanParameterIsDisallowed() {
6663
ConfigurationClassApplicationContext context = new ConfigurationClassApplicationContext(Config.class);
6764
context.getBean((Class<?>)null);
6865
}
69-
66+
7067
@Test
7168
public void addConfigurationClass() {
7269
ConfigurationClassApplicationContext context = new ConfigurationClassApplicationContext();
@@ -77,28 +74,28 @@ public void addConfigurationClass() {
7774
context.refresh();
7875
context.getBean("name");
7976
}
80-
77+
8178
@Test
8279
public void getBeanByType() {
8380
ConfigurationClassApplicationContext context = new ConfigurationClassApplicationContext(Config.class);
8481
TestBean testBean = context.getBean(TestBean.class);
8582
assertNotNull("getBean() should not return null", testBean);
8683
assertThat(testBean.name, equalTo("foo"));
8784
}
88-
85+
8986
/**
9087
* Tests that Configuration classes are registered according to convention
9188
* @see org.springframework.beans.factory.support.DefaultBeanNameGenerator#generateBeanName
9289
*/
9390
@Test
9491
public void defaultConfigClassBeanNameIsGeneratedProperly() {
9592
ConfigurationClassApplicationContext context = new ConfigurationClassApplicationContext(Config.class);
96-
93+
9794
// attempt to retrieve the instance by its generated bean name
9895
Config configObject = (Config) context.getBean(Config.class.getName() + "#0");
9996
assertNotNull(configObject);
10097
}
101-
98+
10299
/**
103100
* Tests that specifying @Configuration(value="foo") results in registering
104101
* the configuration class with bean name 'foo'.
@@ -107,17 +104,17 @@ public void defaultConfigClassBeanNameIsGeneratedProperly() {
107104
public void explicitConfigClassBeanNameIsRespected() {
108105
ConfigurationClassApplicationContext context =
109106
new ConfigurationClassApplicationContext(ConfigWithCustomName.class);
110-
107+
111108
// attempt to retrieve the instance by its specified name
112109
ConfigWithCustomName configObject =
113110
(ConfigWithCustomName) context.getBean("customConfigBeanName");
114111
assertNotNull(configObject);
115112
}
116-
113+
117114
@Test
118115
public void getBeanByTypeRaisesNoSuchBeanDefinitionException() {
119116
ConfigurationClassApplicationContext context = new ConfigurationClassApplicationContext(Config.class);
120-
117+
121118
// attempt to retrieve a bean that does not exist
122119
Class<?> targetType = java.util.regex.Pattern.class;
123120
try {
@@ -128,12 +125,12 @@ public void getBeanByTypeRaisesNoSuchBeanDefinitionException() {
128125
format("No unique bean of type [%s] is defined", targetType.getName())));
129126
}
130127
}
131-
128+
132129
@SuppressWarnings("unchecked")
133130
@Test
134131
public void getBeanByTypeAmbiguityRaisesException() {
135132
ConfigurationClassApplicationContext context = new ConfigurationClassApplicationContext(TwoTestBeanConfig.class);
136-
133+
137134
try {
138135
context.getBean(TestBean.class);
139136
} catch (RuntimeException ex) {
@@ -148,14 +145,14 @@ public void getBeanByTypeAmbiguityRaisesException() {
148145
);
149146
}
150147
}
151-
148+
152149
@Test
153150
public void autowiringIsEnabledByDefault() {
154151
ConfigurationClassApplicationContext context = new ConfigurationClassApplicationContext(AutowiredConfig.class);
155152
assertThat(context.getBean(TestBean.class).name, equalTo("foo"));
156153
}
157-
158-
154+
155+
159156
@Configuration
160157
static class Config {
161158
@Bean
@@ -165,45 +162,45 @@ public TestBean testBean() {
165162
return testBean;
166163
}
167164
}
168-
165+
169166
@Configuration("customConfigBeanName")
170167
static class ConfigWithCustomName {
171168
@Bean
172169
public TestBean testBean() {
173170
return new TestBean();
174171
}
175172
}
176-
173+
177174
static class ConfigMissingAnnotation {
178175
@Bean
179176
public TestBean testBean() {
180177
return new TestBean();
181178
}
182179
}
183-
180+
184181
@Configuration
185182
static class TwoTestBeanConfig {
186183
@Bean TestBean tb1() { return new TestBean(); }
187184
@Bean TestBean tb2() { return new TestBean(); }
188185
}
189-
186+
190187
@Configuration
191188
static class NameConfig {
192189
@Bean String name() { return "foo"; }
193190
}
194-
191+
195192
@Configuration
196193
@Import(NameConfig.class)
197194
static class AutowiredConfig {
198195
@Autowired String autowiredName;
199-
196+
200197
@Bean TestBean testBean() {
201198
TestBean testBean = new TestBean();
202199
testBean.name = autowiredName;
203200
return testBean;
204201
}
205202
}
206-
203+
207204
}
208205

209206
class TestBean {
@@ -233,6 +230,5 @@ public boolean equals(Object obj) {
233230
return false;
234231
return true;
235232
}
236-
237-
238-
}
233+
234+
}

0 commit comments

Comments
 (0)