暫時留個坑: 因爲“Application類”的包名與service的包名不同,導致service下的類無法自動注入。
解決方案:
1 使用@ComponentScan 註解,如下文轉載的文章,但是我自己改了還是有問題,暫時沒找到原因,待補充;
2 將“Application類”與service放到同一個包下 -->可以正常運行
【轉自】http://blog.csdn.net/u014695188/article/details/52263903
- org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.SpringBootJdbcDemoApplication.SpringBootJdbcDemoApplication': Unsatisfied dependency expressed through field 'userRepository': No qualifying bean of type [com.example.repositories.UserRepository] found for dependency [com.example.repositories.UserRepository]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.example.repositories.UserRepository] found for dependency [com.example.repositories.UserRepository]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
- at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569)
- at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
無法注入Dao中的Bean!
解決分析
後來經研究發現,SpringBoot項目的Bean裝配默認規則是根據Application類所在的包位置從上往下掃描!
“Application類”是指SpringBoot項目入口類。這個類的位置很關鍵:
如果Application類所在的包爲:io.github.gefangshuai.app
,則只會掃描io.github.gefangshuai.app
包及其所有子包,如果service或dao所在包不在io.github.gefangshuai.app
及其子包下,則不會被掃描!
知道這一點非常關鍵,不知道spring文檔裏有沒有給出說明,如果不知道還真是無從解決。
轉:http://blog.csdn.NET/gefangshuai/article/details/50328451,http://412887952-qq-com.iteye.com/blog/2292733
在開發中我們知道Spring Boot默認會掃描啓動類同包以及子包下的註解,那麼如何進行改變這種掃描包的方式呢,原理很簡單就是:
@ComponentScan註解進行指定要掃描的包以及要掃描的類。
接下來我們簡單寫個例子進行測試下。
第一步:新建兩個新包
我們在項目中新建兩個包cn.kfit ; org.kfit;
第二步:新建兩個測試類;
在這裏爲了方便測試,我們讓我們的類在啓動的時候就進行執行,所以我們就編寫兩個類,實現接口CommandLineRunner,這樣在啓動的時候我們就可以看到打印信息了。
cn.kfit.MyCommandLineRunner1 :
- package cn.kfit;
- import org.springframework.boot.CommandLineRunner;
- @Configuration
- publicclass MyCommandLineRunner1 implements CommandLineRunner {
- @Override
- publicvoid run(String... args) throws Exception {
- System.out.println("MyCommandLineRunner1.run()");
- }
- }
- package org.kfit;
- import org.springframework.boot.CommandLineRunner;
- @Configuration
- publicclass MyCommandLineRunner2 implements CommandLineRunner {
- @Override
- publicvoid run(String... args) throws Exception {
- System.out.println("MyCommandLineRunner2.run()");
- }
- }
第三步:啓動類進行註解指定
在App.java類中加入如下註解:
- //可以使用:basePackageClasses={},basePackages={}
- @ComponentScan(basePackages={"cn.kfit","org.kfit"})
啓動如果看到打印信息:
- MyCommandLineRunner1.run()
- MyCommandLineRunner2.run()
這時候你會發現,在App.java同包下的都沒有被掃描了,所以如果也希望App.java包下的也同時被掃描的話,那麼在進行指定包掃描的時候一定要進行指定配置:
- @ComponentScan(basePackages={"cn.kfit","org.kfit","com.kfit"})