views:

34

answers:

3

It should be easy:

<bean id="handlerMapping"
   class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
        <list>
            <ref bean="myInterceptor" />
        </list>
    </property>
</bean>

but this way the interceptor isn't called.

+4  A: 

The reason for this behaviour is that two beans of type org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping exist in the application context. Spring resolves the two, but asks only the first for interceptors. To fix this, the following init parameter should be set to the DispatcherServlet

<init-param>
    <param-name>detectAllHandlerMappings</param-name>
    <param-value>false</param-value>
</init-param>

This makes the dispatcher servlet use only the handlerMapping defined in the x-servlet.xml

It is beyond me why this is the default behaviour. I'm expecting an answer from the spring community.

Bozho
The defaults when using the `<mvc>` namespace are wildly confusing. I prefer the older style of specifying everything yourself - the namespace configuration methods seem to rely too much on not-easily-found-in-documentation defaults
matt b
+2  A: 

In Spring MVC 3.0 you can use <mvc:interceptors> instead of manual defining the handler mapping.

axtavt
+1, that's good. But I can't use `ref` there.
Bozho
@Bozho: You can use a `BeanReferenceFactoryBean` (yes, I know that it's ugly).
axtavt
yes, it is :) I think I'll stick to my solution for now.
Bozho
+2  A: 

By default, Spring will register a BeanNameUrlHandlerMapping, and a DefaultAnnotationHandlerMapping, without any explicit config required.

If you define your own HandlerMapping beans, then the default ones will not be registered, and you'll just get the explicitly declared ones.

So far, so good.

The problem comes when you add <mvc:annotation-driven/> to the mix. This also declares its own DefaultAnnotationHandlerMapping, which replaces the defaults. However, if you also declare your own one, then you end up with two. Since they are consulted in order of declaration, this usually means the one registered by <mvc:annotation-driven/> gets called first, and your own one gets ignored.

It would be better if the DefaultAnnotationHandlerMapping registered by <mvc:annotation-driven/> acted like the default one, i.e. if explicitly declared ones took precedence, but that's not the way they wrote it.

My current preference is to not use <mvc:annotation-driven/> at all, it's too confusing, and too unpredictable when mixed with other config options. It doesn't really do anything especially complex, it's not difficult or verbose to explicitly add the stuff that it does for you, and the end result is easier to follow.

skaffman
Good explanation. marking it as accepted. I'll ask another question with what remains unclear - i.e. how to activate parts of what mvc:annotation-driven is doing.
Bozho
https://jira.springsource.org/browse/SPR-6524 seems there is an issue for that, and Juergen Hoeller's comments that this is intended.
Bozho
`<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />` - no need of another question :)
Bozho