diff --git a/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java b/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java index c3985b8934e..a21999ff776 100644 --- a/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java +++ b/org.springframework.aop/src/main/java/org/springframework/aop/config/AopNamespaceUtils.java @@ -19,6 +19,7 @@ package org.springframework.aop.config; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.parsing.ComponentRegistrar; +import org.springframework.beans.factory.parsing.ComponentRegistrarAdapter; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.xml.ParserContext; import org.w3c.dom.Element; @@ -63,7 +64,7 @@ public abstract class AopNamespaceUtils { BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); - registerComponentIfNecessary(beanDefinition, parserContext); + registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext)); } public static void registerAutoProxyCreatorIfNecessary( @@ -86,7 +87,7 @@ public abstract class AopNamespaceUtils { BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); - registerComponentIfNecessary(beanDefinition, parserContext); + registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext)); } public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary( @@ -95,7 +96,7 @@ public abstract class AopNamespaceUtils { BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); - registerComponentIfNecessary(beanDefinition, parserContext); + registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext)); } /** @@ -107,7 +108,7 @@ public abstract class AopNamespaceUtils { public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Object source) { BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary( parserContext.getRegistry(), source); - registerComponentIfNecessary(beanDefinition, parserContext); + registerComponentIfNecessary(beanDefinition, new ComponentRegistrarAdapter(parserContext)); } /** diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/BeanDefinitionRegistrar.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/BeanDefinitionRegistrar.java deleted file mode 100644 index 9184b9c0a3b..00000000000 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/BeanDefinitionRegistrar.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2002-2011 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.beans.factory.parsing; - -import org.springframework.beans.factory.config.BeanDefinition; - -public interface BeanDefinitionRegistrar { - - String registerWithGeneratedName(BeanDefinition beanDefinition); - -} diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrar.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrar.java index 94eb6541b62..45016231d71 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrar.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrar.java @@ -16,9 +16,20 @@ package org.springframework.beans.factory.parsing; -public interface ComponentRegistrar extends BeanDefinitionRegistrar { +import org.springframework.beans.factory.config.BeanDefinition; + +/** + * TODO SPR-7420: document + * + * @author Chris Beams + * @since 3.1 + */ +public interface ComponentRegistrar { + + String registerWithGeneratedName(BeanDefinition beanDefinition); void registerBeanComponent(BeanComponentDefinition component); void registerComponent(ComponentDefinition component); + } diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrarAdapter.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrarAdapter.java new file mode 100644 index 00000000000..36a84706f6a --- /dev/null +++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ComponentRegistrarAdapter.java @@ -0,0 +1,55 @@ +/* + * Copyright 2002-2011 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.beans.factory.parsing; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.xml.ParserContext; + +/** + * TODO SPR-7420: document + *
Adapter is necessary as opposed to having ParserContext
+ * implement ComponentRegistrar directly due to tooling issues.
+ * STS may ship with a version of Spring older that 3.1 (when
+ * this type was introduced), and will run into
+ * IncompatibleClassChangeErrors when it's (3.0.5) ParserContext
+ * tries to mix with our (3.1.0) BeanDefinitionParser
+ * (and related) infrastructure.
+ *
+ * @author Chris Beams
+ * @since 3.1
+ */
+public class ComponentRegistrarAdapter implements ComponentRegistrar {
+
+ private final ParserContext parserContext;
+
+ public ComponentRegistrarAdapter(ParserContext parserContext) {
+ this.parserContext = parserContext;
+ }
+
+ public String registerWithGeneratedName(BeanDefinition beanDefinition) {
+ return this.parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
+ }
+
+ public void registerBeanComponent(BeanComponentDefinition component) {
+ this.parserContext.registerBeanComponent(component);
+ }
+
+ public void registerComponent(ComponentDefinition component) {
+ this.parserContext.registerComponent(component);
+ }
+
+}
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ReaderContext.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ReaderContext.java
index 39c9741a971..64689f6486c 100644
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ReaderContext.java
+++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/parsing/ReaderContext.java
@@ -30,13 +30,12 @@ public class ReaderContext {
private final Resource resource;
+ private final ProblemReporter problemReporter;
+
private final ReaderEventListener eventListener;
private final SourceExtractor sourceExtractor;
- // TODO SPR-7420: review exposing problem reporter
- protected final ProblemReporter problemReporter;
-
public ReaderContext(Resource resource, ProblemReporter problemReporter,
ReaderEventListener eventListener, SourceExtractor sourceExtractor) {
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionReaderUtils.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionReaderUtils.java
index 1d80a290cfc..4407c05902f 100644
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionReaderUtils.java
+++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionReaderUtils.java
@@ -166,12 +166,24 @@ public class BeanDefinitionReaderUtils {
* for the given bean definition or the definition cannot be registered
*/
public static String registerWithGeneratedName(
- AbstractBeanDefinition definition, BeanDefinitionRegistry registry)
+ BeanDefinition definition, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
-
String generatedName = generateBeanName(definition, registry, false);
registry.registerBeanDefinition(generatedName, definition);
return generatedName;
}
+ /**
+ * @deprecated since Spring 3.1 in favor of
+ * {@link #registerWithGeneratedName(BeanDefinition, BeanDefinitionRegistry)}
+ * and its more general signature.
+ */
+ @Deprecated
+ public static String registerWithGeneratedName(
+ AbstractBeanDefinition definition, BeanDefinitionRegistry registry)
+ throws BeanDefinitionStoreException {
+ return registerWithGeneratedName((BeanDefinition)definition, registry);
+
+ }
+
}
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java
index 78ad74e2f2c..c36314c0d14 100644
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java
+++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/ParserContext.java
@@ -21,7 +21,6 @@ import java.util.Stack;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.ComponentDefinition;
-import org.springframework.beans.factory.parsing.ComponentRegistrar;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
@@ -37,7 +36,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
* @see XmlReaderContext
* @see BeanDefinitionParserDelegate
*/
-public final class ParserContext implements ComponentRegistrar {
+public final class ParserContext {
private final XmlReaderContext readerContext;
@@ -122,8 +121,4 @@ public final class ParserContext implements ComponentRegistrar {
registerComponent(component);
}
- public String registerWithGeneratedName(BeanDefinition beanDefinition) {
- return this.readerContext.registerWithGeneratedName(beanDefinition);
- }
-
}
diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlReaderContext.java b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlReaderContext.java
index 8dd361ce399..cbb5a0d5040 100644
--- a/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlReaderContext.java
+++ b/org.springframework.beans/src/main/java/org/springframework/beans/factory/xml/XmlReaderContext.java
@@ -83,9 +83,4 @@ public class XmlReaderContext extends ReaderContext {
return generatedName;
}
- // TODO SPR-7420: review exposing problem reporter
- public ProblemReporter getProblemReporter() {
- return this.problemReporter;
- }
-
}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java
index 1da8a0ef10a..a10f608053f 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ComponentScanBeanDefinitionParser.java
@@ -16,11 +16,9 @@
package org.springframework.context.annotation;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.beans.factory.xml.XmlReaderContext;
-import org.springframework.context.config.SpecificationContext;
+import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
+import org.springframework.context.config.FeatureSpecification;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
@@ -38,11 +36,10 @@ import org.w3c.dom.NodeList;
* @see ComponentScanSpec
* @see ComponentScanExecutor
*/
-public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
+public class ComponentScanBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
- public BeanDefinition parse(Element element, ParserContext parserContext) {
- XmlReaderContext readerContext = parserContext.getReaderContext();
- ClassLoader classLoader = readerContext.getResourceLoader().getClassLoader();
+ public FeatureSpecification doParse(Element element, ParserContext parserContext) {
+ ClassLoader classLoader = parserContext.getReaderContext().getResourceLoader().getClassLoader();
ComponentScanSpec spec =
ComponentScanSpec.forDelimitedPackages(element.getAttribute("base-package"))
@@ -51,7 +48,9 @@ public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
.resourcePattern(element.getAttribute("resource-pattern"))
.beanNameGenerator(element.getAttribute("name-generator"), classLoader)
.scopeMetadataResolver(element.getAttribute("scope-resolver"), classLoader)
- .scopedProxyMode(element.getAttribute("scoped-proxy"));
+ .scopedProxyMode(element.getAttribute("scoped-proxy"))
+ .beanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults())
+ .autowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
// Parse exclude and include filter elements.
NodeList nodeList = element.getChildNodes();
@@ -70,26 +69,7 @@ public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
}
}
- spec.beanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults())
- .autowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns())
- .source(readerContext.extractSource(element))
- .sourceName(element.getTagName())
- .execute(createSpecificationContext(parserContext));
- return null;
- }
-
-
- // Adapt the given ParserContext instance into an SpecificationContext.
- // TODO SPR-7420: create a common ParserContext-to-SpecificationContext adapter utility
- // or otherwise unify these two types
- private SpecificationContext createSpecificationContext(ParserContext parserContext) {
- SpecificationContext specificationContext = new SpecificationContext();
- specificationContext.setRegistry(parserContext.getRegistry());
- specificationContext.setRegistrar(parserContext);
- specificationContext.setResourceLoader(parserContext.getReaderContext().getResourceLoader());
- specificationContext.setEnvironment(parserContext.getDelegate().getEnvironment());
- specificationContext.setProblemReporter(parserContext.getReaderContext().getProblemReporter());
- return specificationContext;
+ return spec;
}
}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java
index 879db9ce04d..e2802254b8c 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassBeanDefinitionReader.java
@@ -107,6 +107,7 @@ class ConfigurationClassBeanDefinitionReader {
this.sourceExtractor = sourceExtractor;
this.problemReporter = problemReporter;
this.metadataReaderFactory = metadataReaderFactory;
+ // TODO SPR-7420: see about passing in the SpecificationContext created in ConfigurationClassPostProcessor
this.specificationContext = new SpecificationContext();
this.specificationContext.setRegistry(this.registry);
this.specificationContext.setRegistrar(new SimpleComponentRegistrar(this.registry));
@@ -171,7 +172,7 @@ class ConfigurationClassBeanDefinitionReader {
}
// no bean definition exists yet -> this must be an imported configuration class (@Import).
- GenericBeanDefinition configBeanDef = new GenericBeanDefinition();
+ BeanDefinition configBeanDef = new GenericBeanDefinition();
String className = configClass.getMetadata().getClassName();
configBeanDef.setBeanClassName(className);
if (checkConfigurationClassCandidate(configBeanDef, this.metadataReaderFactory)) {
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java
index 30a73a78b08..ec1fec1e65e 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java
@@ -354,8 +354,6 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
}
}
- // TODO SPR-7420: consider unifying the two through a superinterface.
- // TODO SPR-7420: create a common ParserContext-to-SpecificationContext adapter util
private SpecificationContext createSpecificationContext(ConfigurableListableBeanFactory beanFactory) {
final BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
SpecificationContext specificationContext = new SpecificationContext();
@@ -363,8 +361,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
specificationContext.setResourceLoader(this.resourceLoader);
specificationContext.setRegistry(registry);
specificationContext.setRegistrar(new SimpleComponentRegistrar(registry));
- // TODO SPR-7420: how to get hold of the current problem reporter here?
- specificationContext.setProblemReporter(new FailFastProblemReporter());
+ specificationContext.setProblemReporter(this.problemReporter);
return specificationContext;
}
diff --git a/org.springframework.context/src/main/java/org/springframework/context/annotation/SimpleComponentRegistrar.java b/org.springframework.context/src/main/java/org/springframework/context/annotation/SimpleComponentRegistrar.java
index 8b9ceb1e898..d812f2983c0 100644
--- a/org.springframework.context/src/main/java/org/springframework/context/annotation/SimpleComponentRegistrar.java
+++ b/org.springframework.context/src/main/java/org/springframework/context/annotation/SimpleComponentRegistrar.java
@@ -20,7 +20,6 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.ComponentDefinition;
import org.springframework.beans.factory.parsing.ComponentRegistrar;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
@@ -30,7 +29,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
* @author Chris Beams
* @since 3.1
*/
-public class SimpleComponentRegistrar implements ComponentRegistrar {
+class SimpleComponentRegistrar implements ComponentRegistrar {
private final BeanDefinitionRegistry registry;
@@ -39,7 +38,7 @@ public class SimpleComponentRegistrar implements ComponentRegistrar {
}
public String registerWithGeneratedName(BeanDefinition beanDefinition) {
- return BeanDefinitionReaderUtils.registerWithGeneratedName((AbstractBeanDefinition)beanDefinition, this.registry);
+ return BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, this.registry);
}
public void registerBeanComponent(BeanComponentDefinition component) {
diff --git a/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationBeanDefinitionParser.java b/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationBeanDefinitionParser.java
new file mode 100644
index 00000000000..61756a97e85
--- /dev/null
+++ b/org.springframework.context/src/main/java/org/springframework/context/config/AbstractSpecificationBeanDefinitionParser.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2002-2011 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.context.config;
+
+import java.lang.reflect.Field;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.parsing.ComponentRegistrarAdapter;
+import org.springframework.beans.factory.parsing.ProblemReporter;
+import org.springframework.beans.factory.parsing.ReaderContext;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.w3c.dom.Element;
+
+/**
+ * TODO SPR-7420: document
+ *
+ * @author Chris Beams
+ * @since 3.1
+ */
+public abstract class AbstractSpecificationBeanDefinitionParser implements BeanDefinitionParser {
+
+ public final BeanDefinition parse(Element element, ParserContext parserContext) {
+ FeatureSpecification spec = doParse(element, parserContext);
+ if (spec instanceof SourceAwareSpecification) {
+ ((SourceAwareSpecification)spec).source(parserContext.getReaderContext().extractSource(element));
+ ((SourceAwareSpecification)spec).sourceName(element.getTagName());
+ }
+ spec.execute(specificationContextFrom(parserContext));
+ return null;
+ }
+
+ abstract protected FeatureSpecification doParse(Element element, ParserContext parserContext);
+
+ /**
+ * Adapt the given ParserContext into a SpecificationContext.
+ */
+ private SpecificationContext specificationContextFrom(ParserContext parserContext) {
+ SpecificationContext specContext = new SpecificationContext();
+ specContext.setRegistry(parserContext.getRegistry());
+ specContext.setRegistrar(new ComponentRegistrarAdapter(parserContext));
+ specContext.setResourceLoader(parserContext.getReaderContext().getResourceLoader());
+ specContext.setEnvironment(parserContext.getDelegate().getEnvironment());
+ try {
+ // access the reader context's problem reporter reflectively in order to
+ // compensate for tooling (STS) constraints around introduction of changes
+ // to parser context / reader context classes.
+ Field field = ReaderContext.class.getDeclaredField("problemReporter");
+ field.setAccessible(true);
+ ProblemReporter problemReporter = (ProblemReporter)field.get(parserContext.getReaderContext());
+ specContext.setProblemReporter(problemReporter);
+ } catch (Exception ex) {
+ throw new IllegalStateException(
+ "Could not access field 'ReaderContext#problemReporter' on object " +
+ parserContext.getReaderContext(), ex);
+ }
+ return specContext;
+ }
+
+}
diff --git a/org.springframework.integration-tests/src/test/java/org/springframework/context/annotation/FeatureTestSuite.java b/org.springframework.integration-tests/src/test/java/org/springframework/context/annotation/FeatureTestSuite.java
index feb52c6196a..5531b325d2c 100644
--- a/org.springframework.integration-tests/src/test/java/org/springframework/context/annotation/FeatureTestSuite.java
+++ b/org.springframework.integration-tests/src/test/java/org/springframework/context/annotation/FeatureTestSuite.java
@@ -73,6 +73,7 @@ import org.springframework.web.servlet.config.MvcViewControllersTests;
MvcResourcesTests.class,
MvcDefaultServletHandlerTests.class,
MvcNamespaceTests.class
+})
*/
public class FeatureTestSuite {
diff --git a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java
index e849cdb80c2..f4b1de641d7 100644
--- a/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java
+++ b/org.springframework.transaction/src/main/java/org/springframework/transaction/config/AnnotationDrivenBeanDefinitionParser.java
@@ -17,10 +17,9 @@
package org.springframework.transaction.config;
import org.springframework.aop.config.AopNamespaceUtils;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.context.config.SpecificationContext;
+import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
+import org.springframework.context.config.FeatureSpecification;
import org.w3c.dom.Element;
/**
@@ -41,7 +40,7 @@ import org.w3c.dom.Element;
* @since 2.0
* @see TxAnnotationDriven
*/
-class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
+class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
/**
* The bean name of the internally managed transaction advisor (mode="proxy").
@@ -61,29 +60,12 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
* {@link AopNamespaceUtils#registerAutoProxyCreatorIfNecessary register an AutoProxyCreator}
* with the container as necessary.
*/
- public BeanDefinition parse(Element element, ParserContext parserContext) {
- new TxAnnotationDriven(element.getAttribute("transaction-manager"))
+ @Override
+ protected FeatureSpecification doParse(Element element, ParserContext parserContext) {
+ return new TxAnnotationDriven(element.getAttribute("transaction-manager"))
.order(element.getAttribute("order"))
.mode(element.getAttribute("mode"))
- .proxyTargetClass(Boolean.valueOf(element.getAttribute("proxy-target-class")))
- .source(parserContext.extractSource(element))
- .sourceName(element.getTagName())
- .execute(createSpecificationContext(parserContext));
- return null;
- }
-
- /**
- * Adapt the given ParserContext instance into an SpecificationContext.
- *
- * TODO SPR-7420: consider unifying the two through a superinterface.
- * TODO SPR-7420: create a common ParserContext-to-SpecificationContext adapter util
- */
- private SpecificationContext createSpecificationContext(ParserContext parserContext) {
- SpecificationContext specificationContext = new SpecificationContext();
- specificationContext.setRegistry(parserContext.getRegistry());
- specificationContext.setRegistrar(parserContext);
- specificationContext.setProblemReporter(parserContext.getReaderContext().getProblemReporter());
- return specificationContext;
+ .proxyTargetClass(Boolean.valueOf(element.getAttribute("proxy-target-class")));
}
}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java
index 88a03de5bc5..9df3b5e135c 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java
@@ -16,12 +16,12 @@
package org.springframework.web.servlet.config;
-import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.context.config.SpecificationContext;
+import org.springframework.context.config.AbstractSpecificationBeanDefinitionParser;
+import org.springframework.context.config.FeatureSpecification;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
@@ -30,22 +30,18 @@ import org.w3c.dom.Element;
* to configure a Spring MVC web application.
*
* @author Rossen Stoyanchev
+ * @author Chris Beams
* @since 3.0
* @see MvcAnnotationDriven
* @see MvcAnnotationDrivenExecutor
*/
-class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
+class AnnotationDrivenBeanDefinitionParser extends AbstractSpecificationBeanDefinitionParser {
/**
* Parses the {@code