Skip to content

Commit bb6349f

Browse files
committed
SimpleMetadataReaderFactory is capable of resolving inner class names with dot syntax now (analogous to ClassUtils.forName)
Issue: SPR-12390 (cherry picked from commit 2d874d7)
1 parent d53b67f commit bb6349f

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 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.
@@ -26,6 +26,7 @@
2626

2727
/**
2828
* @author Chris Beams
29+
* @author Juergen Hoeller
2930
*/
3031
public class ConfigurationClassPostProcessorTests {
3132

@@ -49,6 +50,17 @@ public void testEnhancementIsPresentBecauseSingletonSemanticsAreRespected() {
4950
assertSame(foo, bar.foo);
5051
}
5152

53+
@Test
54+
public void configurationIntrospectionOfInnerClassesWorksWithDotNameSyntax() {
55+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
56+
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(getClass().getName() + ".SingletonBeanConfig"));
57+
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
58+
pp.postProcessBeanFactory(beanFactory);
59+
Foo foo = beanFactory.getBean("foo", Foo.class);
60+
Bar bar = beanFactory.getBean("bar", Bar.class);
61+
assertSame(foo, bar.foo);
62+
}
63+
5264
/**
5365
* Tests the fix for SPR-5655, a special workaround that prefers reflection
5466
* over ASM if a bean class is already loaded.

spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReaderFactory.java

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2009 the original author or authors.
2+
* Copyright 2002-2014 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.
@@ -73,7 +73,23 @@ public final ResourceLoader getResourceLoader() {
7373
public MetadataReader getMetadataReader(String className) throws IOException {
7474
String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +
7575
ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX;
76-
return getMetadataReader(this.resourceLoader.getResource(resourcePath));
76+
Resource resource = this.resourceLoader.getResource(resourcePath);
77+
if (!resource.exists()) {
78+
// Maybe an inner class name using the dot name syntax? Need to use the dollar syntax here...
79+
// ClassUtils.forName has an equivalent check for resolution into Class references later on.
80+
int lastDotIndex = className.lastIndexOf('.');
81+
if (lastDotIndex != -1) {
82+
String innerClassName =
83+
className.substring(0, lastDotIndex) + '$' + className.substring(lastDotIndex + 1);
84+
String innerClassResourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +
85+
ClassUtils.convertClassNameToResourcePath(innerClassName) + ClassUtils.CLASS_FILE_SUFFIX;
86+
Resource innerClassResource = this.resourceLoader.getResource(innerClassResourcePath);
87+
if (innerClassResource.exists()) {
88+
resource = innerClassResource;
89+
}
90+
}
91+
}
92+
return getMetadataReader(resource);
7793
}
7894

7995
public MetadataReader getMetadataReader(Resource resource) throws IOException {

0 commit comments

Comments
 (0)