mvc:annotation-driven註解的作用
一、<mvc:annotation-driven />註解意義
主要就是為了Spring MVC來用的,提供Controller請求轉發,json自動轉換等功能
<mvc:annotation-driven /> 是一種簡寫形式,完全可以手動配置替代這種簡寫形式,簡寫形式可以讓初學都快速應用預設配置方案。配置一些messageconverter。即解決了@Controller註解的使用前提配置<context:annotation-config/>是對包進行掃描,實現註釋驅動Bean定義,同時將bean自動注入容器中使用。即解決了@Controller標識的類的bean的注入和使用。 <mvc:annotation-driven>會自動註冊RequestMappingHandlerMapping與RequestMappingHandlerAdapter兩個Bean,這是Spring MVC為@Controller分發請求所必需的,並且提供了資料繫結支援,@NumberFormatannotation支援,@DateTimeFormat支援,@Valid支援讀寫XML的支援(JAXB)和讀寫JSON的支援(預設Jackson)等功能。 我們處理響應ajax請求時,就使用到了對json的支援。 對action寫JUnit單元測試時,要從spring IOC容器中取DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean,來完成測試,取的時候要知道是<mvc:annotation-driven />這一句註冊的這兩個bean。
<!-- spring 可以自動去掃描 base-package下面的包或子包下面的Java檔案,如果掃描到有Spring的相關 註解的類,則把這些類註冊為Spring的bean --> <context:component-scan base-package="org.fkit.controller"/> <!--設定配置方案 --> <mvc:annotation-driven/> <!--使用預設的Servlet來響應靜態檔案--> <mvc:default-servlet-handler/> <!-- 檢視解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 字首 --> <property name="prefix"> <value>/WEB-INF/content/</value> </property> <!-- 字尾 --> <property name="suffix"> <value>.jsp</value> </property> </bean>
一開始我在寫配置的時候,只寫了<context:component-scan/>,並沒有使用<mvc:annotation-driven/>,servlet攔截*.do,.do請求可以被正確捕捉和處理。
後來為了解決靜態資源訪問的問題,servlet改成了攔截所有請求,即/,並添加了預設的servlet,這時候*.do請求不能被控制器捕捉了,頁面錯誤為404。直到添加了<mvc:annotation-driven/>之後,.do請求才又能被正確捕捉和處理。
<context:component-scan base-package="com"></context:component-scan> <mvc:annotation-driven/> <mvc:resources mapping="/styles/**" location="/WEB-INF/resource/styles/"/> <mvc:default-servlet-handler/>
當我們需要controller返回一個map的json物件時,可以設定<mvc:annotation-driven />,
同時設定<mvc:message-converters> 標籤,設定字符集和json處理類,例如:
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
二、<context:annotation-config/> 註解
當我們需要使用BeanPostProcessor時,直接在Spring配置檔案中定義這些Bean顯得比較笨拙,例如: 使用@Autowired註解,必須事先在Spring容器中宣告AutowiredAnnotationBeanPostProcessor的Bean
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor "/>
使用 @Required註解,就必須宣告RequiredAnnotationBeanPostProcessor的Bean:
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
類似地,使用@Resource、@PostConstruct、@PreDestroy等註解就必須宣告 CommonAnnotationBeanPostProcessor;使用@PersistenceContext註解,就必須宣告 PersistenceAnnotationBeanPostProcessor的Bean。 這樣的宣告未免太不優雅,而Spring為我們提供了一種極為方便註冊這些BeanPostProcessor的方式,即使用<context:annotation- config/>隱式地向 Spring容器註冊AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor以及PersistenceAnnotationBeanPostProcessor這4個BeanPostProcessor。如下:
<context:annotation-config/>
另,在我們使用註解時一般都會配置掃描包路徑選項:
<context:component-scan base-package="pack.pack"/>
該配置項其實也包含了自動注入上述processor的功能,因此當使用<context:component-scan/>後,即可將<context:annotation-config/>省去。
備註: 在配置檔案中使用 context 名稱空間之前,必須在 <beans> 元素中宣告 context 名稱空間。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">
<mvc:resources mapping="/favicon.ico" location="/favicon.ico,classpath:/favicon.ico" />
<mvc:resources mapping="/public/**" location="/public/,classpath:/public/" />
<mvc:resources mapping="/platform/**" location="/platform/" />
<bean class="org.springframework.http.converter.ResourceHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>application/json; charset=UTF-8</value>
<value>*; charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="org.springframework.http.converter.ResourceHttpMessageConverter" />
<ref bean="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="detectHandlersInAncestorContexts" value="true" />
</bean>
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPaths">
<list>
<value>/WEB-INF/ftl</value>
<value>classpath:/ftl</value>
</list>
</property>
<property name="preferFileSystemAccess" value="false" />
<property name="freemarkerSettings">
<props>
<prop key="defaultEncoding">UTF-8</prop>
<prop key="url_escaping_charset">UTF-8</prop>
<prop key="locale">zh_CN</prop>
</props>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="cache" value="true" />
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html; charset=UTF-8" />
<property name="requestContextAttribute" value="rc"></property>
</bean>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
</beans>