Skip to content

Commit 2d874d7

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 725ad0d)
1 parent 91940f2 commit 2d874d7

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

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

+10
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ public void enhancementIsPresentBecauseSingletonSemanticsAreRespected() {
8585
assertSame(foo, bar.foo);
8686
}
8787

88+
@Test
89+
public void configurationIntrospectionOfInnerClassesWorksWithDotNameSyntax() {
90+
beanFactory.registerBeanDefinition("config", new RootBeanDefinition(getClass().getName() + ".SingletonBeanConfig"));
91+
ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
92+
pp.postProcessBeanFactory(beanFactory);
93+
Foo foo = beanFactory.getBean("foo", Foo.class);
94+
Bar bar = beanFactory.getBean("bar", Bar.class);
95+
assertSame(foo, bar.foo);
96+
}
97+
8898
/**
8999
* Tests the fix for SPR-5655, a special workaround that prefers reflection
90100
* 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-2012 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.
@@ -74,7 +74,23 @@ public final ResourceLoader getResourceLoader() {
7474
public MetadataReader getMetadataReader(String className) throws IOException {
7575
String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +
7676
ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX;
77-
return getMetadataReader(this.resourceLoader.getResource(resourcePath));
77+
Resource resource = this.resourceLoader.getResource(resourcePath);
78+
if (!resource.exists()) {
79+
// Maybe an inner class name using the dot name syntax? Need to use the dollar syntax here...
80+
// ClassUtils.forName has an equivalent check for resolution into Class references later on.
81+
int lastDotIndex = className.lastIndexOf('.');
82+
if (lastDotIndex != -1) {
83+
String innerClassName =
84+
className.substring(0, lastDotIndex) + '$' + className.substring(lastDotIndex + 1);
85+
String innerClassResourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +
86+
ClassUtils.convertClassNameToResourcePath(innerClassName) + ClassUtils.CLASS_FILE_SUFFIX;
87+
Resource innerClassResource = this.resourceLoader.getResource(innerClassResourcePath);
88+
if (innerClassResource.exists()) {
89+
resource = innerClassResource;
90+
}
91+
}
92+
}
93+
return getMetadataReader(resource);
7894
}
7995

8096
@Override

0 commit comments

Comments
 (0)