diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/ext/Bean.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/ext/Bean.java index a5872313f6680ab28fe908d65ce7eeac73814f18..bf505f7945eac49d71e249255b2b777c2e0686c2 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/ext/Bean.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/ext/Bean.java @@ -67,8 +67,7 @@ import org.springframework.config.java.Validator; @Documented @Factory(registrarType=BeanRegistrar.class, callbackType=BeanMethodInterceptor.class, - validatorTypes={BeanValidator.class, - IllegalBeanOverrideValidator.class}) + validatorTypes={BeanValidator.class, IllegalBeanOverrideValidator.class}) public @interface Bean { /** diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/factory/support/AsmJavaConfigBeanDefinitionReader.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/factory/support/ConfigurationClassBeanDefinitionReader.java similarity index 73% rename from org.springframework.config.java/src/main/java/org/springframework/config/java/internal/factory/support/AsmJavaConfigBeanDefinitionReader.java rename to org.springframework.config.java/src/main/java/org/springframework/config/java/internal/factory/support/ConfigurationClassBeanDefinitionReader.java index 8df795743b395e740939fb492cb3bef16d9ad82c..b4ccfac4147a82ce2dd21ef0d0874a6727c0d913 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/factory/support/AsmJavaConfigBeanDefinitionReader.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/factory/support/ConfigurationClassBeanDefinitionReader.java @@ -15,23 +15,17 @@ */ package org.springframework.config.java.internal.factory.support; -import static org.springframework.config.java.Util.*; - import java.util.ArrayList; import java.util.Map; -import org.objectweb.asm.ClassReader; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.support.BeanDefinitionReader; -import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.config.java.Configuration; import org.springframework.config.java.ConfigurationModel; import org.springframework.config.java.MalformedJavaConfigurationException; import org.springframework.config.java.UsageError; import org.springframework.config.java.internal.parsing.ConfigurationParser; -import org.springframework.config.java.internal.parsing.asm.AsmConfigurationParser; -import org.springframework.config.java.internal.parsing.asm.AsmUtils; import org.springframework.core.io.ClassPathResource; @@ -44,17 +38,17 @@ import org.springframework.core.io.ClassPathResource; * * @author Chris Beams */ -public class AsmJavaConfigBeanDefinitionReader { +public class ConfigurationClassBeanDefinitionReader { private final ConfigurationModelBeanDefinitionReader modelBeanDefinitionReader; /** - * Creates a new {@link AsmJavaConfigBeanDefinitionReader}. + * Creates a new {@link ConfigurationClassBeanDefinitionReader}. * - * @param registry {@link BeanDefinitionRegistry} into which new bean definitions will be + * @param beanFactory {@link DefaultListableBeanFactory} into which new bean definitions will be * registered as they are read from Configuration classes. */ - public AsmJavaConfigBeanDefinitionReader(DefaultListableBeanFactory beanFactory) { + public ConfigurationClassBeanDefinitionReader(DefaultListableBeanFactory beanFactory) { this.modelBeanDefinitionReader = new ConfigurationModelBeanDefinitionReader(beanFactory); } @@ -64,13 +58,10 @@ public class AsmJavaConfigBeanDefinitionReader { * supplied during construction. */ public int loadBeanDefinitions(ConfigurationModel model, Map configClassResources) throws BeanDefinitionStoreException { - ConfigurationParser parser = new AsmConfigurationParser(model); + ConfigurationParser parser = new ConfigurationParser(model); - for (String id : configClassResources.keySet()) { - String resourcePath = configClassResources.get(id).getPath(); - ClassReader configClassReader = AsmUtils.newClassReader(getClassAsStream(resourcePath)); - parser.parse(configClassReader, id); - } + for (String id : configClassResources.keySet()) + parser.parse(configClassResources.get(id), id); ArrayList errors = new ArrayList(); model.validate(errors); diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/AnnotationAdapter.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/AnnotationAdapter.java similarity index 97% rename from org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/AnnotationAdapter.java rename to org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/AnnotationAdapter.java index 94ec8d30b261b30263653d3df443fa2449dfd3f1..759a8f3b387011e02b20f5bd200a88285a6f9d54 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/AnnotationAdapter.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/AnnotationAdapter.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.config.java.internal.parsing.asm; +package org.springframework.config.java.internal.parsing; import org.objectweb.asm.AnnotationVisitor; diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/AsmUtils.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/AsmUtils.java similarity index 98% rename from org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/AsmUtils.java rename to org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/AsmUtils.java index af57d7dc440419e07e5fa2b216944550e9b2feec..70d62f07b86522687ffc24f69b27e075e405fac6 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/AsmUtils.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/AsmUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.config.java.internal.parsing.asm; +package org.springframework.config.java.internal.parsing; import java.io.IOException; import java.io.InputStream; diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/ConfigurationClassMethodVisitor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/ConfigurationClassMethodVisitor.java similarity index 96% rename from org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/ConfigurationClassMethodVisitor.java rename to org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/ConfigurationClassMethodVisitor.java index 4cd215545999207fd7ab773235456dcda7a221de..2fdda4f14781bc7abb34b8280870c0bc36c593f1 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/ConfigurationClassMethodVisitor.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/ConfigurationClassMethodVisitor.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.config.java.internal.parsing.asm; +package org.springframework.config.java.internal.parsing; import static org.springframework.config.java.Util.*; -import static org.springframework.config.java.internal.parsing.asm.AsmUtils.*; -import static org.springframework.config.java.internal.parsing.asm.MutableAnnotationUtils.*; +import static org.springframework.config.java.internal.parsing.AsmUtils.*; +import static org.springframework.config.java.internal.parsing.MutableAnnotationUtils.*; import static org.springframework.util.ClassUtils.*; import java.lang.annotation.Annotation; diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/ConfigurationClassVisitor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/ConfigurationClassVisitor.java similarity index 98% rename from org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/ConfigurationClassVisitor.java rename to org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/ConfigurationClassVisitor.java index 6e0d93041beb1769a2ba3de079f0cd2d7a4fada2..016effa90ee6502bda9df1b77c34f2e4fbb913f0 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/ConfigurationClassVisitor.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/ConfigurationClassVisitor.java @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.config.java.internal.parsing.asm; +package org.springframework.config.java.internal.parsing; import static org.springframework.config.java.Util.*; -import static org.springframework.config.java.internal.parsing.asm.MutableAnnotationUtils.*; +import static org.springframework.config.java.internal.parsing.MutableAnnotationUtils.*; import static org.springframework.util.ClassUtils.*; import java.lang.annotation.Annotation; diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/ConfigurationParser.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/ConfigurationParser.java index 53eb4c91d2ae9ea436e9b47609cecc322d1d42a4..2d7db11d42fc9cf5016222fad139a768d73ad71a 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/ConfigurationParser.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/ConfigurationParser.java @@ -15,46 +15,65 @@ */ package org.springframework.config.java.internal.parsing; + + +import org.objectweb.asm.ClassReader; +import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.config.java.Configuration; +import org.springframework.config.java.ConfigurationClass; import org.springframework.config.java.ConfigurationModel; +import org.springframework.config.java.Util; +import org.springframework.core.io.ClassPathResource; /** - * Parses a {@link Configuration} class definition, usually into a {@link ConfigurationModel}. + * Parses a {@link Configuration} class definition, populating a {@link ConfigurationModel}. + * This ASM-based implementation avoids reflection and eager classloading in order to + * interoperate effectively with tooling (Spring IDE) and OSGi environments. *

- * This interface aids in separating the process of reading a class file (via reflection, ASM, etc) - * from the process of registering bean definitions based on the content of that class. + * This class helps separate the concern of parsing the structure of a Configuration class + * from the concern of registering {@link BeanDefinition} objects based on the content of + * that model. * - * @see org.springframework.config.java.internal.parsing.asm.AsmConfigurationParser * @see org.springframework.config.java.ConfigurationModel * @see org.springframework.config.java.internal.factory.support.ConfigurationModelBeanDefinitionReader - * + * * @author Chris Beams - */ -public interface ConfigurationParser { + */ +public class ConfigurationParser { /** - * Parse the Configuration object represented by configurationSource. - * - * @param configurationSource representation of a Configuration class, may be java.lang.Class, - * ASM representation or otherwise - * - * @see org.springframework.config.java.Configuration + * Model to be populated during calls to {@link #parse(Object, String)} */ - void parse(Object configurationSource); + private final ConfigurationModel model; /** - * Optionally propagate a custom name for this configurationSource. Usually this id - * corresponds to the name of a Configuration bean as declared in a beans XML. + * Creates a new parser instance that will be used to populate model. * - * @param configurationSource representation of a Configuration class, may be java.lang.Class, - * ASM representation or otherwise - * @param configurationId name of this configuration class, probably corresponding to a - * bean id + * @param model model to be populated by each successive call to {@link #parse(Object, String)} + */ + public ConfigurationParser(ConfigurationModel model) { + this.model = model; + } + + /** + * Parse the {@link Configuration @Configuration} class encapsulated by + * configurationSource. * - * @see org.springframework.config.java.Configuration - * @see org.springframework.config.java.process.ConfigurationPostProcessor + * @param configurationSource reader for Configuration class being parsed + * @param configurationId may be null, but if populated represents the bean id + * (assumes that this configuration class was configured via XML) */ - void parse(Object configurationSource, String configurationId); + public void parse(ClassPathResource resource, String configurationId) { + + String resourcePath = resource.getPath(); + ClassReader configClassReader = AsmUtils.newClassReader(Util.getClassAsStream(resourcePath)); + + ConfigurationClass configClass = new ConfigurationClass(); + configClass.setBeanName(configurationId); + + configClassReader.accept(new ConfigurationClassVisitor(configClass, model), false); + model.add(configClass); + } } diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotation.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotation.java similarity index 96% rename from org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotation.java rename to org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotation.java index 2c967aca9631e9d5ca7367ca03afc31f28f9c1fd..b2417c0aee420a920bf79e0d7ed8d0fad0f9220d 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotation.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotation.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.config.java.internal.parsing.asm; +package org.springframework.config.java.internal.parsing; /** diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationArrayVisitor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationArrayVisitor.java similarity index 93% rename from org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationArrayVisitor.java rename to org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationArrayVisitor.java index c82acb21b15bfeef35ced2b8f4a36a67a2bfd49d..b67f034e4ccf214f0070172112b07790578640b4 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationArrayVisitor.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationArrayVisitor.java @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.config.java.internal.parsing.asm; +package org.springframework.config.java.internal.parsing; import static org.springframework.config.java.Util.*; -import static org.springframework.config.java.internal.parsing.asm.MutableAnnotationUtils.*; +import static org.springframework.config.java.internal.parsing.MutableAnnotationUtils.*; import java.lang.annotation.Annotation; import java.lang.reflect.Array; diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationInvocationHandler.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationInvocationHandler.java similarity index 99% rename from org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationInvocationHandler.java rename to org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationInvocationHandler.java index 0c360079544ec8e6d8a8d15fba1a6e75ff8565f2..f33ba0e8954e83569c2e8919f03be5d4f4bed60d 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationInvocationHandler.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationInvocationHandler.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.config.java.internal.parsing.asm; +package org.springframework.config.java.internal.parsing; import static java.lang.String.*; import static org.springframework.core.annotation.AnnotationUtils.*; diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationUtils.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationUtils.java similarity index 96% rename from org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationUtils.java rename to org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationUtils.java index 8b23606191b241c538f3d83dfb27f7f1b812660d..e4c1fbadd09b6805b508b9cc4427087472a199c4 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationUtils.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationUtils.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.config.java.internal.parsing.asm; +package org.springframework.config.java.internal.parsing; import java.lang.annotation.Annotation; import java.lang.reflect.Proxy; diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationVisitor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationVisitor.java similarity index 96% rename from org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationVisitor.java rename to org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationVisitor.java index b652159c5730162ce611db637fd3143b2a2b5b7b..2d92ac1a955c4b02c0a4dcef1dae45e35998928c 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/MutableAnnotationVisitor.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/MutableAnnotationVisitor.java @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.config.java.internal.parsing.asm; +package org.springframework.config.java.internal.parsing; import static org.springframework.config.java.Util.*; -import static org.springframework.config.java.internal.parsing.asm.MutableAnnotationUtils.*; +import static org.springframework.config.java.internal.parsing.MutableAnnotationUtils.*; import java.lang.annotation.Annotation; import java.lang.reflect.Field; diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/AsmConfigurationParser.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/AsmConfigurationParser.java deleted file mode 100644 index 62d9128a5da865a92fc8f6492196b0c231af3517..0000000000000000000000000000000000000000 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/parsing/asm/AsmConfigurationParser.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2002-2008 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.springframework.config.java.internal.parsing.asm; - - - -import org.objectweb.asm.ClassReader; -import org.springframework.config.java.Configuration; -import org.springframework.config.java.ConfigurationClass; -import org.springframework.config.java.ConfigurationModel; -import org.springframework.config.java.internal.parsing.ConfigurationParser; -import org.springframework.util.Assert; - - -/** - * ASM-based implementation of {@link ConfigurationParser}. Avoids reflection and eager classloading - * in order to interoperate effectively with tooling (Spring IDE). - * - * @see org.springframework.config.java.model.AsmConfigurationParserTests - - * @author Chris Beams - */ -public class AsmConfigurationParser implements ConfigurationParser { - - /** - * Model to be populated during calls to {@link #parse(Object)} - */ - private final ConfigurationModel model; - - /** - * Creates a new parser instance that will be used to populate model. - * - * @param model model to be populated by each successive call to {@link #parse(Object)} - */ - public AsmConfigurationParser(ConfigurationModel model) { - this.model = model; - } - - /** - * Convenience implementation, delegates to {@link #parse(Object, String)}, - * passing in {@code null} for the configurationId. - * - * @param configurationSource must be an ASM {@link ClassReader} - */ - public void parse(Object configurationSource) { - parse(configurationSource, null); - } - - /** - * Parse the {@link Configuration @Configuration} class encapsulated by - * configurationSource. - * - * @param configurationSource must be an ASM {@link ClassReader} - * @param configurationId may be null, but if populated represents the bean id - * (assumes that this configuration class was configured via XML) - */ - public void parse(Object configurationSource, String configurationId) { - Assert.isInstanceOf(ClassReader.class, configurationSource, - "configurationSource must be an ASM ClassReader"); - - ConfigurationClass configClass = new ConfigurationClass(); - configClass.setBeanName(configurationId); - - parse((ClassReader) configurationSource, configClass); - } - - /** - * Kicks off visiting configClass with {@link ConfigurationClassVisitor} - */ - private void parse(ClassReader reader, ConfigurationClass configClass) { - reader.accept(new ConfigurationClassVisitor(configClass, model), false); - model.add(configClass); - } - -} diff --git a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/process/InternalConfigurationPostProcessor.java b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/process/InternalConfigurationPostProcessor.java index caf916a3e2846d55d54d1608dd937a1e633f49a1..cfe4500c0160b3db81bc7fa28352d8618a8a24d1 100644 --- a/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/process/InternalConfigurationPostProcessor.java +++ b/org.springframework.config.java/src/main/java/org/springframework/config/java/internal/process/InternalConfigurationPostProcessor.java @@ -17,6 +17,7 @@ package org.springframework.config.java.internal.process; import static org.springframework.config.java.Util.*; +import java.util.ArrayList; import java.util.LinkedHashMap; import org.apache.commons.logging.Log; @@ -29,8 +30,12 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.config.java.Configuration; import org.springframework.config.java.ConfigurationModel; +import org.springframework.config.java.MalformedJavaConfigurationException; +import org.springframework.config.java.UsageError; import org.springframework.config.java.internal.enhancement.ConfigurationEnhancer; -import org.springframework.config.java.internal.factory.support.AsmJavaConfigBeanDefinitionReader; +import org.springframework.config.java.internal.factory.support.ConfigurationClassBeanDefinitionReader; +import org.springframework.config.java.internal.factory.support.ConfigurationModelBeanDefinitionReader; +import org.springframework.config.java.internal.parsing.ConfigurationParser; import org.springframework.config.java.process.ConfigurationPostProcessor; import org.springframework.core.io.ClassPathResource; import org.springframework.util.ClassUtils; @@ -46,19 +51,21 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces * to parse and enhance them. Also registers any {@link BeanPostProcessor} objects * necessary to fulfill JavaConfig requirements. */ - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - if(!(beanFactory instanceof DefaultListableBeanFactory)) + public void postProcessBeanFactory(ConfigurableListableBeanFactory clBeanFactory) throws BeansException { + if(!(clBeanFactory instanceof DefaultListableBeanFactory)) throw new IllegalStateException("beanFactory must be of type " + DefaultListableBeanFactory.class.getSimpleName()); + DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) clBeanFactory; + ConfigurationModel model = new ConfigurationModel(); parseAnyConfigurationClasses(beanFactory, model); - enhanceAnyConfigurationClasses((DefaultListableBeanFactory) beanFactory, model); + enhanceAnyConfigurationClasses(beanFactory, model); } - private void parseAnyConfigurationClasses(ConfigurableListableBeanFactory beanFactory, ConfigurationModel model) { + private void parseAnyConfigurationClasses(DefaultListableBeanFactory beanFactory, ConfigurationModel model) { // linked map is important for maintaining predictable ordering of configuration classes. // this is important in bean / value override situations. @@ -75,7 +82,18 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces } } - beanDefinitionReader(beanFactory).loadBeanDefinitions(model, configClassResources); + ConfigurationModelBeanDefinitionReader modelBeanDefinitionReader = new ConfigurationModelBeanDefinitionReader(beanFactory); + ConfigurationParser parser = new ConfigurationParser(model); + + for (String id : configClassResources.keySet()) + parser.parse(configClassResources.get(id), id); + + ArrayList errors = new ArrayList(); + model.validate(errors); + if (errors.size() > 0) + throw new MalformedJavaConfigurationException(errors.toArray(new UsageError[] { })); + + modelBeanDefinitionReader.loadBeanDefinitions(model); } /** @@ -96,7 +114,6 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces for (String beanName : beanFactory.getBeanDefinitionNames()) { BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName); - // is the beanDef marked as representing a configuration class? if (!isConfigClass(beanDef)) continue; @@ -117,15 +134,6 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces logger.warn("Found no @Configuration class BeanDefinitions within " + beanFactory); } - private AsmJavaConfigBeanDefinitionReader beanDefinitionReader(ConfigurableListableBeanFactory beanFactory) { - // reader requires DefaultListableBeanFactory for it's registerBeanDefinition() method - if(!(beanFactory instanceof DefaultListableBeanFactory)) - throw new IllegalStateException("beanFactory must be of type " - + DefaultListableBeanFactory.class.getSimpleName()); - - return new AsmJavaConfigBeanDefinitionReader((DefaultListableBeanFactory)beanFactory); - } - /** * Determines whether the class for beanDef is a {@link Configuration}-annotated * class. Returns false if beanDef has no class specified. @@ -133,7 +141,7 @@ public class InternalConfigurationPostProcessor implements BeanFactoryPostProces * 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 use {@link AsmJavaConfigBeanDefinitionReader}directly, + * any case, tooling (Spring IDE) will use {@link ConfigurationClassBeanDefinitionReader}directly, * thus never encountering 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