問題點:在springboot 多模塊項目中,新建了一個子模塊,然后子模塊的其中一個類注入了另一個模塊的類,啟動項目出現(xiàn)Could not autowire. No beans of 'SysLoginService' type found.的報錯。

如上圖所示,新建子模塊youxi-mobile,有個WxLoginController控制器,類中利用@Autowired注解將
youxi-framework 中的SysLoginService類屬性注入到里面。
結(jié)果就出現(xiàn)了這樣的錯誤,無法自動注入,找不到SysLoginService類

首先我排查了youxi-mobile的pom.xml文件,看是否引入youxi-framework 的依賴,發(fā)現(xiàn)并沒有問題

查找資料發(fā)現(xiàn)一種解決方法,就是在啟動類的@SpringBootApplication注解上加上scanBasePackages = "com"

加上后發(fā)現(xiàn)沒問題了

這時候我就有點奇怪,那為什么我的另一個子模塊youxi-admin的啟動類上并沒有加上scanBasePackages = "com",同樣跟上面一樣進行屬性注入就不會報錯。

然后繼續(xù)谷歌,又發(fā)現(xiàn)了一個知識點
有這樣一個注解@ComponentScan,源碼
package org.springframework.context.annotation;
@Retention(RetentionPolicy.RUNTIME)
//表示只可以聲明在類上
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value") //表示和value等價
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
@ComponentScan 的作用就是根據(jù)定義的掃描路徑,把符合掃描規(guī)則的類裝配到spring容器中
本質(zhì)上,SpringBootApplicatioscan中的scanBasePackages屬性底層原理正是復用了@ComponentScan,因此語法和意義基本一致
public @interface SpringBootApplication {
//復用了@ComponentScan
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};
@AliasFor標簽表示別名的意義,可以理解為等價于
因此,下面2種用法相同:
@SpringBootApplication (scanBasePackages="com.youxi")
public class YouXiApplication{
package com.test;
@ComponentScan("com.youxi")
@SpringBootApplication
public class YouXiApplication{
SpringBoot項目中
當使用Spring Boot項目時,可以不指定加載路徑,即不使用@ComponentScan或@SpringBootApplication (scanBasePackages="com.youxi"),默認會加載YouXiApplication所在的包
舉個例子,看下面定義的類:
package com.youxi;
@SpringBootApplication
public class YouXiApplication{
YouXiApplication的package為com.youxi,這個類使用了@SpringBootApplication注解,該注解定義了Spring將自動掃描包com.youxi及其子包下的bean。
如果你項目中所有的類都定義在com.youxi包及其子包下,那你不需要做任何事。
但假如你一個類定義在包com.youxi2下,則你需要將這個新包也納入掃描的范圍,有兩個方案可以達到這個目的:
方案1, 定義@CoponentScan(“com”)
這么做掃描的范圍擴大到整個父包com
方案2, 定義分別掃描兩個包
@ComponentScan({“com.youxi”,”com.youxi2”})
所以經(jīng)過我的觀察,我發(fā)現(xiàn)我的youxi-admin項目的啟動類是在com.youxi目錄下

根據(jù)上面的說法,會自動掃描自動掃描包com.youxi及其子包下的bean。查看目錄結(jié)構(gòu),youxi-framework項目中SysLoginService類所在的包確實是在com.youxi 目錄下,所以當youxi-admin項目啟動時,就會自動掃描到。

這時候看一下新創(chuàng)建的youxi-mobile

真相大白了??!YouxiMobileApplication啟動類在com.youxi.mobile這個包目錄下,所以項目啟動后會到com.youxi.mobile這個目錄下掃描有沒有SysLoginService類,很顯然,SysLoginService類并不存在于com.youxi.mobile下,所以這里只需要把啟動類所在包目錄改成com.youxi就可以了!
總結(jié)
雖然這只是個小問題,但也能反應出我對這方面的了解還是不夠深不夠扎實,所以寫下了這篇文章,記錄我踩過的坑,給大家提供一個解決這方面問題的思路同時方便以后查看~