原創播客,如需轉載請注明出處。原文地址:http://www.cnblogs.com/crawl/p/7940755.html
----------------------------------------------------------------------------------------------------------------------------------------------------------
筆記中提供了必要的代碼示例,需要說明的是,大部分代碼示例都是本人所敲代碼並進行測試,不足之處,請大家指正~
本博客中所有言論僅代表博主本人觀點,若有疑惑或者需要本系列分享中的資料工具,敬請聯系 qingqing_crawl@163.com
-----------------------------------------------------------------------------------------------------------------------------------------------------------
前言:昨天在做一個小項目時先對 SSM 進行整合,一通配置之后進行測試,發現啟動 Tomcat 就出錯了,錯誤信息如下:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mybatis.ssm.service.EmployeeService com.mybatis.ssm.controller.EmployeeController.employeeService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mybatis.ssm.service.EmployeeService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mybatis.ssm.service.EmployeeService com.mybatis.ssm.controller.EmployeeController.employeeService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mybatis.ssm.service.EmployeeService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
查看錯誤信息應該是說沒有掃描到樓主的 Service,經過一番排查之后,樓主將錯誤定位到了包掃描的配置上,其實也就是 use-default-filters 配置的問題上。
Step 1:先看一下樓主的 SpringMVC 和 Spring 的配置文件中對包掃描的配置:
SpringMVC:
1 <!-- 配置自動掃描的包 --> 2 <context:component-scan base-package="com.mybatis.ssm" use-default-filters="false"> 3 <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 4 </context:component-scan>
Spring:
1 <!-- 配置自動掃描的包 --> 2 <context:component-scan base-package="com.mybatis.ssm" use-default-filters="false"> 3 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 4 </context:component-scan>
SpringMVC 主要就是來管理網站的跳轉邏輯,所以在配置掃描的包時,使用 use-default-filters 屬性,並設置為 false,即不使用默認的 Filter 進行掃描。
而 Spring 的配置文件中,樓主也想當然的配置了 use-default-filters 為 false,正式這個配置,導致出錯。
Step 2:錯誤分析
要分析這個錯誤,就要先了解 use-default-filters 這個屬性的作用。use-default-filters 屬性的默認值為 true,即使用默認的 Filter 進行包掃描,而默認的 Filter 對標有 @Service,@Controller和@Repository 的注解的類進行掃描,因為前面說過,我們希望 SpringMVC 只來控制網站的跳轉邏輯,所以我們只希望 SpringMVC 的配置掃描 @Controllerce 注解標注的類,不希望它掃描其余注解標注的類,所以設置了 use-default-filters 為 false,並使用 context:include-filter 子標簽設置其只掃描帶有 @Controller 注解標注的類。
而 Spring 就不同了,我們希望 Spring 只不掃描帶有 @Controller 注解標注的類,而掃描其他注解標注的類,而這時建立在使用默認的 Filter 進行掃描的基礎上,設置了 context:exclude-filter 標簽,不掃描 @Controller 注解標注的類,所以不應該設置 use-default-filters 為 false,所以這就解釋了為什么一開始啟動 Tomcat 時報了一個找不到 Service 的錯誤。
Step 3:總結
在使用 use-default-filters 屬性時要分清楚需要掃描哪些包,是不是需要使用默認的 Filter 進行掃描。樓主稍微總結一下,即 use-default-filters="false" 需要和 context:include-filter 一起使用,而不能和 context:exclude-filter 屬性一起使用。
Step 4:更正
Spring 的配置文件中包掃描配置如下:
1 <!-- 配置自動掃描的包 --> 2 <context:component-scan base-package="com.mybatis.ssm"> 3 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 4 </context:component-scan>
這樣更正過來之后,再啟動 Tomcat 就沒有錯誤了!