SpringBoot bean無法注入的問題

暫時留個坑: 因爲“Application類”的包名與service的包名不同,導致service下的類無法自動注入。

解決方案:

1 使用@ComponentScan 註解,如下文轉載的文章,但是我自己改了還是有問題,暫時沒找到原因,待補充;

2 將“Application類”與service放到同一個包下  -->可以正常運行


【轉自】http://blog.csdn.net/u014695188/article/details/52263903

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. 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)}  
  2.     at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569)  
  3.     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  : 

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package cn.kfit;  
  2.   
  3. import org.springframework.boot.CommandLineRunner;  
  4.   
  5. @Configuration  
  6. publicclass MyCommandLineRunner1 implements CommandLineRunner {  
  7.   
  8.     @Override  
  9.     publicvoid run(String... args) throws Exception {  
  10.        System.out.println("MyCommandLineRunner1.run()");  
  11.   
  12.     }  
  13. }  
org.kfit.MyCommandLineRunner2  : 
[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. package org.kfit;  
  2.   
  3. import org.springframework.boot.CommandLineRunner;  
  4.   
  5.   
  6. @Configuration  
  7. publicclass MyCommandLineRunner2 implements CommandLineRunner {  
  8.   
  9.     @Override  
  10.     publicvoid run(String... args) throws Exception {  
  11.   
  12.        System.out.println("MyCommandLineRunner2.run()");  
  13.   
  14.     }  
  15.   
  16. }  

第三步:啓動類進行註解指定
在App.java類中加入如下註解:

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. //可以使用:basePackageClasses={},basePackages={}  
  2. @ComponentScan(basePackages={"cn.kfit","org.kfit"})  

 
啓動如果看到打印信息:

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. MyCommandLineRunner1.run()  
  2. MyCommandLineRunner2.run()  
說明我們配置成功了。

這時候你會發現,在App.java同包下的都沒有被掃描了,所以如果也希望App.java包下的也同時被掃描的話,那麼在進行指定包掃描的時候一定要進行指定配置:

[html] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. @ComponentScan(basePackages={"cn.kfit","org.kfit","com.kfit"})  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章