();
model.validate(errors);
if (errors.size() > 0)
throw new MalformedConfigurationException(errors.toArray(new UsageError[] {}));
-
- modelBeanDefinitionReader.loadBeanDefinitions(model);
}
/**
@@ -118,55 +167,43 @@ public class ConfigurationPostProcessor implements Ordered, BeanFactoryPostProce
* @see ConfigurationEnhancer
* @see BeanFactoryPostProcessor
*/
- private void enhanceAnyConfigurationClasses(DefaultListableBeanFactory beanFactory,
- ConfigurationModel model) {
-
- ConfigurationEnhancer enhancer = new ConfigurationEnhancer(beanFactory, model);
+ private void enhanceConfigurationClasses() {
- int configClassesEnhanced = 0;
-
- for (String beanName : beanFactory.getBeanDefinitionNames()) {
+ ConfigurationEnhancer enhancer = new ConfigurationEnhancer(beanFactory);
+
+ BeanDefinitionRegistry configBeanDefs = getConfigurationBeanDefinitions(true);
+
+ for(String beanName : configBeanDefs.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
-
- if (!isConfigClass(beanDef))
- continue;
-
String configClassName = beanDef.getBeanClassName();
-
String enhancedClassName = enhancer.enhance(configClassName);
if (logger.isDebugEnabled())
- logger
- .debug(String
- .format(
- "Replacing bean definition '%s' existing class name '%s' with enhanced class name '%s'",
- beanName, configClassName, enhancedClassName));
+ logger.debug(format("Replacing bean definition '%s' existing class name '%s' with enhanced class name '%s'",
+ beanName, configClassName, enhancedClassName));
beanDef.setBeanClassName(enhancedClassName);
-
- configClassesEnhanced++;
}
-
- if (configClassesEnhanced == 0)
- logger.warn("Found no @Configuration class BeanDefinitions within " + beanFactory);
}
/**
* Determines whether the class for beanDef is a {@link Configuration}
* -annotated class. Returns false if beanDef has no class specified.
- *
- * Note: the classloading used within should not be problematic or interfere with
- * tooling in any way. BeanFactoryPostProcessing happens only during actual runtime
- * processing via {@link JavaConfigApplicationContext} or via XML using
- * {@link ConfigurationPostProcessor}. In any case, tooling (Spring IDE) will hook in at
- * a lower level than this class and thus never encounter this classloading. Should this
- * become problematic, it would not be too difficult to replace the following with ASM
- * logic that traverses the class hierarchy in order to find whether the class is
- * directly or indirectly annotated with {@link Configuration}.
*/
private static boolean isConfigClass(BeanDefinition beanDef) {
+
String className = beanDef.getBeanClassName();
- return className != null && loadRequiredClass(className).isAnnotationPresent(Configuration.class);
+
+ if(className == null)
+ return false;
+
+ try {
+ MetadataReader metadataReader = new SimpleMetadataReaderFactory().getMetadataReader(className);
+ AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
+ return annotationMetadata.hasAnnotation(Configuration.class.getName());
+ } catch (IOException ex) {
+ throw new RuntimeException(ex);
+ }
}
}
diff --git a/org.springframework.config.java/src/test/java/test/basic/AutowiredConfigurationTests.xml b/org.springframework.config.java/src/test/java/test/basic/AutowiredConfigurationTests.xml
index 124dee31a36..ffdd961b422 100644
--- a/org.springframework.config.java/src/test/java/test/basic/AutowiredConfigurationTests.xml
+++ b/org.springframework.config.java/src/test/java/test/basic/AutowiredConfigurationTests.xml
@@ -11,4 +11,5 @@
+
diff --git a/org.springframework.config.java/src/test/java/test/basic/BasicTests.java b/org.springframework.config.java/src/test/java/test/basic/BasicTests.java
index 116d18c89b6..8e499b05798 100644
--- a/org.springframework.config.java/src/test/java/test/basic/BasicTests.java
+++ b/org.springframework.config.java/src/test/java/test/basic/BasicTests.java
@@ -10,6 +10,7 @@ import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostP
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.config.java.Configuration;
+import org.springframework.config.java.MalformedConfigurationException;
import org.springframework.config.java.Scopes;
import org.springframework.config.java.ext.Bean;
import org.springframework.config.java.support.ConfigurationPostProcessor;
@@ -100,4 +101,63 @@ public class BasicTests {
return new TestBean("bar");
}
}
+
+
+ @Test
+ public void legalBeanOverriding() {
+ {
+ BeanFactory factory = initBeanFactory(ConfigWithBeanThatAllowsOverriding.class, ConfigWithBeanOverride.class);
+
+ TestBean testBean = factory.getBean("testBean", TestBean.class);
+
+ assertThat(testBean.getName(), equalTo("overridden"));
+ }
+
+ // now try it the other way around - order matters!
+
+ {
+ BeanFactory factory = initBeanFactory(ConfigWithBeanOverride.class, ConfigWithBeanThatAllowsOverriding.class);
+
+ TestBean testBean = factory.getBean("testBean", TestBean.class);
+
+ assertThat(testBean.getName(), equalTo("original"));
+ }
+
+ }
+
+ @Test(expected=MalformedConfigurationException.class)
+ public void illegalBeanOverriding() {
+ initBeanFactory(ConfigWithBeanThatDisallowsOverriding.class, ConfigWithBeanOverride.class);
+ }
+
+ @Test
+ public void illegalBeanOverriding2() {
+ // should be okay when the class that disallows overriding is the one doing the overriding
+ initBeanFactory(ConfigWithBeanOverride.class, ConfigWithBeanThatDisallowsOverriding.class);
+ }
+
+ @Configuration
+ static class ConfigWithBeanThatAllowsOverriding {
+ @Bean
+ public TestBean testBean() {
+ return new TestBean("original");
+ }
+ }
+
+ @Configuration
+ static class ConfigWithBeanThatDisallowsOverriding {
+ @Bean(allowOverriding = false)
+ public TestBean testBean() {
+ return new TestBean("original");
+ }
+ }
+
+ @Configuration
+ static class ConfigWithBeanOverride {
+ @Bean
+ public TestBean testBean() {
+ return new TestBean("overridden");
+ }
+ }
+
}
diff --git a/org.springframework.config.java/src/test/java/test/basic/ValueInjectionTests.xml b/org.springframework.config.java/src/test/java/test/basic/ValueInjectionTests.xml
index a2e19889067..d89442c0191 100644
--- a/org.springframework.config.java/src/test/java/test/basic/ValueInjectionTests.xml
+++ b/org.springframework.config.java/src/test/java/test/basic/ValueInjectionTests.xml
@@ -10,4 +10,8 @@
+
+