天天看點

Spring配置檔案中的那些标簽

context:annotation-config

它的作用是隐式地向Spring容器注冊AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor這4個BeanPostProcessor。其作用是如果你想在程式中使用注解,就必須先注冊該注解對應的類,如下圖所示:

 依賴的類  注解
 CommonAnnotationBeanPostProcessor     @Resource 、@PostConstruct、@PreDestroy   
 PersistenceAnnotationBeanPostProcessor     @PersistenceContext   
 AutowiredAnnotationBeanPostProcessor     @Autowired   
 RequiredAnnotationBeanPostProcessor     @Required   

另外還支援:@WebServiceRef,@EJB,@PersistenceUnit。

注意:

這個标簽不會激活處理Spring的@Transactional或EJB3的@TransactionAttribute注解。 考慮使用<tx:annotation-driven>标簽。

context:component-scan

掃描classpath時,被注釋的元件将自動注冊為Spring bean。 預設情況下,Spring提供的@Component,@Repository,@Service和@Controller原型會被檢測到。

這個标簽的存在意味可以不在xml中配置<context:annotation-config>标簽了。因為該标簽會支援@Required,@Autowired,@PostConstruct,@PreDestroy,@Resource,@PersistenceContext和@PersistenceUnit這些注釋,這通常是自動檢測元件的理想選擇(沒有外部配置)。 當然你可以選擇設定annotation-config屬性為false來棄用這個預設行為,該屬性預設為true。例如當你想使用自定義的BeanPostProcessor來處理這些注釋的時候你可以這麼做。

另外需要注意:當Spring配置需要檔案分層的時候,該标簽應該保證每一個配置檔案都配置一次。這時就有點兒講究了,SpringMVC的dispatcher-servlet.xml配置檔案可以隻掃描帶有@Controller注解的類,而在Spring的applicationContext.xml檔案中則可以掃描其他所有帶有注解的類(也可以過濾掉帶@Controller注解的類)。

除了必須指定的屬性base-package之外,<context:component-scan/>還可以指定如下屬性:

  • resource-pattern:表示可以被自動檢測的Class的形式,預設為“**/*.class”,即所有的class檔案。這個隻是用來告訴Spring需要對哪些檔案進行掃描,而并不是把它們自動定義為對應的bean。這個需要與後續需要介紹的filter區分開。
  • use-default-filters:表示使用使用預設的filter,。<context:component-scan/>将把哪些Class自動注冊到bean容器是由對應的filter來控制的。該屬性的值預設為true,即預設會使用預設的filter。而預設的filter會将标注了@Component、@Controller、@Service和@Repository的類,包括這四個注解所标注的注解所标注的類,都會将它們自動注冊到bean容器中。
  • annotation-config:是否啟用對注解的支援,即隐式的啟用<context:annotation-config/>,預設為true。
  • name-generator:預設的beanName生成器,即在沒有顯式的指定beanName時,自動注冊的bean将如何使用預設的beanName。預設将使用Class的簡稱,即不包含包名的類名稱,并将首字母小寫作為目前bean的名稱。使用者可以通過實作org.springframework.beans.factory.support.BeanNameGenerator接口并指定其為目前的name-generator來改變對應的政策。
  • scope-resolver:指定用于解析bean定義的scope的ScopeMetadataResolver,預設将通過AnnotationScopeMetadataResolver進行解析,而該解析器将根據類上标注的@Scope注解來解析對應的scope。預設沒有指定@Scope的都是單例。
  • scoped-proxy:表示是否需要為自動檢測到的需要加入bean容器中的bean生成對應的代理。預設是不生成。可選值有“no”、“interfaces”和“targetClass”,分别對應不生成、根據接口生成和根據目标class生成。這對需要使用代理的scope是非常有必須要的,如request、session等。更詳細的内容請參考先前專門介紹scope的那篇文章。

mvc:annotation-driven

<mvc:annotation-driven/>會自動注冊LocaleResolver,ThemeResolver,HandlerMapping,HandlerAdapter,HandlerExceptionResolver,RequestToViewNameTranslator,ViewResolver,FlashMapManager這8個元件的實作類,這8個元件便是SpringMVC的核心元件。程式在運作時會先去容器中掃描看是否你自定義了某一元件的實作,如果沒有的話就使用properties檔案中預設定義的實作類。

<mvc:annotation-driven/>标簽對應的解析類是AnnotationDrivenBeanDefinitionParser。從其中可以看出,該标簽為我們做了這些配置:

  • 支援使用了像@RquestMapping、@ExceptionHandler等等的注解的controller方法去處理請求。
  • 支援使用@RequestBody、@ResponseBody注解。
  • 并提供了:資料綁定支援,@NumberFormat注解的支援對資料類型進行格式化,@DateTimeFormat支援
  • 支援使用@Valid對javaBean進行JSR-303驗證。
  • 讀寫XML的支援(JAXB),讀寫JSON的支援(Jackson)。

對于HttpMessageConverter,它到底是幹什麼的呢?它是用來将特定的對象轉換成字元串并最終作為HttpResponse傳回的工具。實際上SpringMVC中面向開發人員的業務邏輯處理主要集中在各種Controller的方法中,基本模式是接受代表着HttpRequest的各種輸入參數,在方法體中進行業務邏輯處理,最後得到輸出結果,并以傳回值的形式交給SpringMvc,Springmvc根據傳回值的不同調用不同的處理邏輯并最終以HttpResponse的形式傳回給用戶端。Controller中的傳回值可以有很多種,比如字元串,ModelAndView,普通對象,等等,甚至void類型都是可以的。是以SpringMvc會根據傳回值的類型做很多的if else,不同的類型調用不同的處理邏輯。那麼當函數接受@ResponseBody聲明時,Spring就會嘗試用配置好的各種HttpMessageConverter來将傳回值進行序列化。不同HttpMessageConverter能夠處理的對象以及處理方式都是不一樣的,Spring會周遊各Converter,如果該Converter能夠處理該對象則交由其處理。是以,很多基于Spring的REST風格的應用常常會傳回一個model對象,那麼你就應該配置好正确的HttpMessageConverter,以便Spring能夠正确的将這些對象序列化回用戶端。

mvc:default-servlet-handler

其實當一個請求來到的時候,它的執行流程是先經過tomcat的servlet的url-pattern的比對。進入到了SpringMVC,然後對于SpringMVC架構來說,為了處理對應的請求時,首先會去找對應的HandlerMapping看是否有對應的類來處理該請求,如果有的話再根據HandlerAdapter去找是什麼類,以及對應的處理方法。找不到的時候會報404。但當配置了<mvc:default-servlet-handler>标簽的時候,它會注冊SimpleUrlHandlerMapping來處理請求映射,對應的Handler是DefaultServletHttpRequestHandler,這種情況一般是其他HandlerMapping無法比對處理,最後才無奈交給DefaultServletHttpRequestHandler來處理。而該Handler具體的做法其實就是轉發給了web容器自身的defaultServlet來處理。這個servlet名稱可以在mvc:default-servlet-handler标簽中進行配置,如果沒有配置,采用預設的配置,tomcat預設的servlet名稱為default。即tomcat、Jetty等,在容器啟動的時候,自身就預設注冊了一個name叫default的servlet,DefaultServletHttpRequestHandler就是轉發給這些servlet。defaultServlet會去尋找有沒有該檔案,找到了解析并傳回檔案内容,比如我們常請求的jsp頁面,就是通過JspServlet來進行翻譯的。找不到則404。但是你可以通過自定義servlet來替換defaultServlet。給使用者傳回自定義的一些資訊。

mvc:resources

<mvc:default-servlet-handler />将靜态資源的處理經由Spring MVC架構交回Web應用伺服器處理。而<mvc:resources />更進一步,由Spring MVC架構自己處理靜态資源,并添加一些有用的附加值功能。<mvc:resources />允許靜态資源放在任何地方,如WEB-INF目錄下、類路徑下等,你甚至可以将JavaScript等靜态檔案打到JAR包中。通過location屬性指定靜态資源的位置,由于location屬性是Resources類型,是以可以使用諸如classpath:等的資源字首指定資源位置。傳統Web容器的靜态資源隻能放在Web容器的根路徑下,<mvc:resources />完全打破了這個限制。

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources/ directory -->
<resources mapping="/resources/**" location="/resources/" />      

時刻與技術進步,每天一點滴,日久一大步!!!

本部落格隻為記錄,用于學習,如有冒犯,請私信于我。