From 725ad0df50aec9f193f35f8a08244575214c8577 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 29 Oct 2014 22:03:01 +0100 Subject: [PATCH] SimpleMetadataReaderFactory is capable of resolving inner class names with dot syntax now (analogous to ClassUtils.forName) Issue: SPR-12390 --- .../ConfigurationClassPostProcessorTests.java | 10 ++++++++++ .../SimpleMetadataReaderFactory.java | 20 +++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java index 0a3b790228..421e738214 100644 --- a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassPostProcessorTests.java @@ -86,6 +86,16 @@ public class ConfigurationClassPostProcessorTests { assertSame(foo, bar.foo); } + @Test + public void configurationIntrospectionOfInnerClassesWorksWithDotNameSyntax() { + beanFactory.registerBeanDefinition("config", new RootBeanDefinition(getClass().getName() + ".SingletonBeanConfig")); + ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor(); + pp.postProcessBeanFactory(beanFactory); + Foo foo = beanFactory.getBean("foo", Foo.class); + Bar bar = beanFactory.getBean("bar", Bar.class); + assertSame(foo, bar.foo); + } + /** * Tests the fix for SPR-5655, a special workaround that prefers reflection * over ASM if a bean class is already loaded. diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReaderFactory.java b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReaderFactory.java index 667bac6882..c4af45418b 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReaderFactory.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMetadataReaderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -74,7 +74,23 @@ public class SimpleMetadataReaderFactory implements MetadataReaderFactory { public MetadataReader getMetadataReader(String className) throws IOException { String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX; - return getMetadataReader(this.resourceLoader.getResource(resourcePath)); + Resource resource = this.resourceLoader.getResource(resourcePath); + if (!resource.exists()) { + // Maybe an inner class name using the dot name syntax? Need to use the dollar syntax here... + // ClassUtils.forName has an equivalent check for resolution into Class references later on. + int lastDotIndex = className.lastIndexOf('.'); + if (lastDotIndex != -1) { + String innerClassName = + className.substring(0, lastDotIndex) + '$' + className.substring(lastDotIndex + 1); + String innerClassResourcePath = ResourceLoader.CLASSPATH_URL_PREFIX + + ClassUtils.convertClassNameToResourcePath(innerClassName) + ClassUtils.CLASS_FILE_SUFFIX; + Resource innerClassResource = this.resourceLoader.getResource(innerClassResourcePath); + if (innerClassResource.exists()) { + resource = innerClassResource; + } + } + } + return getMetadataReader(resource); } @Override