如何摆脱 <mvc:annotation-driven />?
Posted
技术标签:
【中文标题】如何摆脱 <mvc:annotation-driven />?【英文标题】:Howto get rid of <mvc:annotation-driven />? 【发布时间】:2011-04-11 05:45:33 【问题描述】:到目前为止,<mvc:annotation-driven />
给我带来了很多麻烦,所以我想摆脱它。虽然spring framework docs clearly say what it is supposed to be doing,但实际上总结<mvc:annotation-driven />
的标签列表是缺乏的。
所以我坚持删除<mvc:annotation-driven />
,现在得到错误
警告 o.s.web.servlet.PageNotFound - 没有为 HTTP 请求找到映射 URI [/webapp/trainees] 在 带名称的 DispatcherServlet '锻炼传感器'
对于所有应该由控制器类解析的 URL(在本例中为:./trainees
)。有什么建议可以让我了解更多关于<mvc:annotation-driven />
的信息吗?我非常想知道<mvc:annotation-driven />
到底代表了哪些标签。
【问题讨论】:
【参考方案1】:如果你想避免mvc:annotation-driven
标签,你可以简单地自己创建DefaultAnnotationHandlerMapping
和AnnotationMethodHandlerAdapter
bean,但听起来最好还是用标签本身来解决问题的根源。
您的问题的症状是什么?你想用你的 Spring MVC 应用程序做什么?
如果您想知道使用 mvc:annotation-driven 时幕后发生了什么,请参阅AnnotationDrivenBeanDefinitionParser
.parse()
方法。
【讨论】:
“您的问题的症状是什么?” - O,只是每当我自定义一个 Spring 安全接口(例如 UserDetailsManager)时,我都会收到“双重定义”错误。或者当我尝试定义自己的方面时,我的永远不会被阅读,因为 spring 使用它自己的。此外,我感觉更好地控制我的代码。约定优于配置是一件好事......如果你知道约定是什么;-)【参考方案2】:您可以使用BeanPostProcessor
自定义<mvc:annotation-driven />
定义的每个bean。 javadocs 现在详细说明了标记注册的所有 bean。
如果真想去掉,可以看org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParser
的源码
你可以看到它定义了哪些bean。我已经完成了这个“练习”(不是针对所有人,而是针对我需要的人),所以它们是:
<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">
现在,您可以在上方看到CommonWebBindingInitializer
。您必须创建此类,才能使用转换和验证:
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);
到目前为止,这对我来说效果很好。如有任何问题,请随时报告。
【讨论】:
感谢 Bozho,这正是我需要的输入。我很确定我会遇到更多的配置问题,尤其是实现AnnotationDrivenBeanDefinitionParser
源代码也可以在 GitHub 上查看:github.com/cbeams/spring-framework/blob/master/…【参考方案3】:
我知道的老问题,但这可能对某人有所帮助。感谢此页面上的帖子以及 over here,我使用以下内容替换了 Roo 1.2 应用程序中的注释驱动标签。对我来说,他们需要在 roo 应用列表视图中支持类型转换。
<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>
【讨论】:
Spring 3.1 为 @RequestMapping 引入了 new support classes,它应该用于“利用 Spring MVC 3.1 的新特性”。已更新此示例。【参考方案4】:在覆盖时,请谨慎考虑自定义执行管理覆盖。否则,您的所有自定义异常映射都将失败。您将不得不重用带有列表 bean 的 messageCoverters:
<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>
【讨论】:
以上是关于如何摆脱 <mvc:annotation-driven />?的主要内容,如果未能解决你的问题,请参考以下文章