Howto get rid of <mvc:annotation-driven />?
Asked Answered
A

4

15

Up to now, <mvc:annotation-driven /> has caused plenty of trouble for me, so I would like to get rid of it. Although the spring framework docs clearly say what it is supposed to be doing, a listing of tags actually summar <mvc:annotation-driven /> is lacking.

So I'm stuck with removing <mvc:annotation-driven /> and now getting the error

WARN o.s.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/webapp/trainees] in DispatcherServlet with name 'workoutsensor'

for all Urls supposed to be resolved by the controller classes (in this case: ./trainees). Any suggestion where I can read more about <mvc:annotation-driven />? I desperately would like to know what tags exactly are represented by <mvc:annotation-driven />.

Atom answered 12/9, 2010 at 1:36 Comment(0)
O
26

You can use BeanPostProcessor to customize each bean defined by <mvc:annotation-driven />. The javadocs now details all beans the tag registers.

If you really want to get rid of it, you can look at the source code of org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser

And you can see which beans it is defining. I've done this 'exercise' (not for all of them, but for those I need), so here are they:

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="webBindingInitializer">
            <bean class="com.yourpackage.web.util.CommonWebBindingInitializer" />
        </property>
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
                <bean class="org.springframework.http.converter.ResourceHttpMessageConverter" />
                <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
                <bean class="org.springframework.http.converter.feed.AtomFeedHttpMessageConverter" />
                <bean class="org.springframework.http.converter.feed.RssChannelHttpMessageConverter" />
                <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
                <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
                <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter" />
                <!-- bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" /-->
            </list>
        </property>
    </bean>
<bean id="handlerMapping"
    class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">

Now, above you see the CommonWebBindingInitializer. You have to create this class, in order to use conversion and validation:

public class CommonWebBindingInitializer implements WebBindingInitializer {

    @Autowired
    private Validator validator;

    @Autowired
    private ConversionService conversionService;

    @Override
    public void initBinder(WebDataBinder binder, WebRequest request) {
        binder.setValidator(validator);
        binder.setConversionService(conversionService);
    }

}

And this works fine for me so far. Feel free to report any problems with it.

Orangeism answered 12/9, 2010 at 7:12 Comment(3)
Thanks Bozho, that is just the input I need. I am quite sure that I will run into further config problems, in particular, implementing <remember-me/>. I won't hesitate reporting them ;-)Atom
Ah, there is the Fisheye link I was looking for. :]Rakel
BTW AnnotationDrivenBeanDefinitionParser source may be viewed also at GitHub: github.com/cbeams/spring-framework/blob/master/…Nosing
R
5

If you want to avoid the mvc:annotation-driven tag, you can simply create DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter beans yourself, but it sounds like it would be better to get to the root of your troubles with the tag itself.

What are the symptoms of your problem? What are you trying to do with your Spring MVC application?

If you want to know what's going on under the covers when you use mvc:annotation-driven, see the AnnotationDrivenBeanDefinitionParser.parse() method.

Rakel answered 12/9, 2010 at 4:13 Comment(1)
"What are the symptoms of your problem?" - O, it's just that whenever I customize a spring security interface (e.g. UserDetailsManager) I get a "double defined" error. Or when I try and define my own aspects, mine are never read because spring uses its own. Furthermore, I feel better having some more control over what I code. Convention-over-configuration is a great thing ... if you know what the convention is ;-)Atom
P
4

Old question I know, but this may help someone. Thanks to posts on this page and also over here, I've used the following to replace the annotation-driven tag in Roo 1.2 app. They kicker for me was needing support type conversion in roo app list view.

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />

<bean id="conversionServiceExposingInterceptor"
    class="org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor">
    <constructor-arg ref="conversionService" />
</bean>

<bean
    class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
    <property name="order" value="0" />
    <property name="interceptors">
        <list>
            <ref bean="conversionServiceExposingInterceptor" />
        </list>
    </property>
</bean>

<bean
    class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="webBindingInitializer">
        <bean
            class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <property name="conversionService" ref="conversionService" />
            <property name="validator" ref="validator" />
        </bean>
    </property>
    <property name="messageConverters">
        <list>
            <bean
                class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
            <bean
                class="org.springframework.http.converter.StringHttpMessageConverter" />
            <bean class="org.springframework.http.converter.FormHttpMessageConverter" />
            <bean
                class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
        </list>
    </property>
</bean>
Particia answered 9/2, 2012 at 17:29 Comment(1)
Spring 3.1 introduced new support classes for @RequestMapping which should be used "to take advantage of new Spring MVC 3.1 features". Have updated this example.Particia
S
2

While overriding, be carreful to consider also custom Execution management overriding. Otherwise, all your custom Exception mappings will fail. You will have to reuse messageCoverters with a list bean :

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />

<util:list id="messageConverters">
    <bean class="your.custom.message.converter.IfAny"></bean>
    <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
    <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
</util:list>

<bean name="exceptionHandlerExceptionResolver"
      class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
    <property name="order" value="0"/>
    <property name="messageConverters" ref="messageConverters"/>
</bean>

<bean name="handlerAdapter"
      class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="webBindingInitializer">
        <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <property name="conversionService" ref="conversionService" />
            <property name="validator" ref="validator" />
        </bean>
    </property>
    <property name="messageConverters" ref="messageConverters"/>
</bean>

<bean id="handlerMapping"
      class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
</bean>
Silvern answered 23/12, 2013 at 12:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.