diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotatedControllersBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotatedControllersBeanDefinitionParser.java index ddc12a7401..1429d07e9f 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotatedControllersBeanDefinitionParser.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotatedControllersBeanDefinitionParser.java @@ -16,9 +16,15 @@ package org.springframework.web.servlet.config; -import org.springframework.beans.factory.support.AbstractBeanDefinition; -import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.BeanDefinitionHolder; +import org.springframework.beans.factory.parsing.BeanComponentDefinition; +import org.springframework.beans.factory.parsing.CompositeComponentDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter; +import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping; import org.w3c.dom.Element; /** @@ -27,11 +33,38 @@ import org.w3c.dom.Element; * * @author Keith Donald */ -public class AnnotatedControllersBeanDefinitionParser extends AbstractBeanDefinitionParser { +public class AnnotatedControllersBeanDefinitionParser implements BeanDefinitionParser { - @Override - protected AbstractBeanDefinition parseInternal(Element element, ParserContext context) { - throw new UnsupportedOperationException("Not yet implemented"); + public BeanDefinition parse(Element element, ParserContext parserContext) { + Object source = parserContext.extractSource(element); + BeanDefinitionHolder handlerMappingHolder = registerDefaultAnnotationHandlerMapping(element, source, parserContext); + BeanDefinitionHolder handlerAdapterHolder = registerAnnotationMethodHandlerAdapter(element, source, parserContext); + + CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source); + parserContext.pushContainingComponent(compDefinition); + parserContext.registerComponent(new BeanComponentDefinition(handlerMappingHolder)); + parserContext.registerComponent(new BeanComponentDefinition(handlerAdapterHolder)); + parserContext.popAndRegisterContainingComponent(); + + return null; + } + + private BeanDefinitionHolder registerDefaultAnnotationHandlerMapping(Element element, Object source, ParserContext context) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DefaultAnnotationHandlerMapping.class); + builder.addPropertyValue("order", 0); + builder.getRawBeanDefinition().setSource(source); + return registerBeanDefinition(new BeanDefinitionHolder(builder.getBeanDefinition(), "defaultAnnotationHandlerMapping"), context); + } + + private BeanDefinitionHolder registerAnnotationMethodHandlerAdapter(Element element, Object source, ParserContext context) { + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(AnnotationMethodHandlerAdapter.class); + builder.getRawBeanDefinition().setSource(source); + return registerBeanDefinition(new BeanDefinitionHolder(builder.getBeanDefinition(), "annotationMethodHandlerAdapter"), context); + } + + private BeanDefinitionHolder registerBeanDefinition(BeanDefinitionHolder holder, ParserContext context) { + context.getRegistry().registerBeanDefinition(holder.getBeanName(), holder.getBeanDefinition()); + return holder; } } diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java new file mode 100644 index 0000000000..c703743d30 --- /dev/null +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java @@ -0,0 +1,36 @@ +package org.springframework.web.servlet.config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.springframework.core.io.ClassPathResource; +import org.springframework.mock.web.MockServletContext; +import org.springframework.web.context.support.GenericWebApplicationContext; +import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter; +import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping; + +public class MvcNamespaceTests { + + private GenericWebApplicationContext container; + + @Before + public void setUp() { + container = new GenericWebApplicationContext(); + container.setServletContext(new MockServletContext()); + } + + @Test + public void testDefaultConfig() { + XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(container); + reader.loadBeanDefinitions(new ClassPathResource("mvc-config.xml", getClass())); + assertEquals(2, container.getBeanDefinitionCount()); + DefaultAnnotationHandlerMapping mapping = container.getBean("defaultAnnotationHandlerMapping", DefaultAnnotationHandlerMapping.class); + assertNotNull(mapping); + assertEquals(0, mapping.getOrder()); + AnnotationMethodHandlerAdapter adapter = container.getBean("annotationMethodHandlerAdapter", AnnotationMethodHandlerAdapter.class); + assertNotNull(adapter); + } +} diff --git a/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config.xml b/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config.xml new file mode 100644 index 0000000000..3525d84869 --- /dev/null +++ b/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/config/mvc-config.xml @@ -0,0 +1,10 @@ + + + + + +