Bean 注入失敗問題匯總
閱讀本文大概需要 5 分鐘。
來(lái)自:blog.csdn.net/qq_51439643/article/details/124781526
目錄
錯(cuò)誤案例 常見情況一:bean 沒有被掃描 常見情況二:多模塊架構(gòu) bean 沒有被掃描 常見情況三:使用 @Qualifier或@Resource注入時(shí)指定的 name 不存在常見情況四:在攔截器或過濾器或監(jiān)聽器中注入 bean 使用 IDEA 工具查看 IOC 容器
錯(cuò)誤案例
常見情況一:bean 沒有被掃描

com.training 包下放置主函數(shù)與服務(wù)代碼,在 com.utils 包下放置一些配置與工具類。com.training,所以在com.training包與其子包下的 Bean 會(huì)被默認(rèn)自動(dòng)掃描加入到 Spring 容器中。com.utils 包不包含在默認(rèn)掃描的包之內(nèi),就算是將 bean1 對(duì)象使用注解嘗試注入容器,Spring 也不會(huì)掃描到該類,因此這是大部分 bean 注入失敗的原因。com.utils 包加入到掃描中,可以使用 @ComponentScan 指定額外的掃描包,配置如下:package com.training;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
// 將com.utils 包加入到 Spring 掃描范圍中
@ComponentScan(basePackages = {"com.training","com.utils"})
@MapperScan(basePackages = "com.training.dao")
public class MusicMainClass {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(MusicMainClass.class, args);
}
}
@ComponetScan 后默認(rèn)的掃描位置會(huì)發(fā)生改變,因此添加新的掃描包后要確保啟動(dòng)類所在的包也能被掃描到!@ComponentScan 進(jìn)行配置,@SpringBootApplication 中的 scanBasePackages 屬性指定也能起到同樣的作用,配置方式如下:package com.training;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
// 使用 scanBasePackages 屬性同樣能夠?qū)崿F(xiàn)
@SpringBootApplication(scanBasePackages = {"com.training","com.utils"})
@MapperScan(basePackages = "com.training.dao")
public class MusicMainClass {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(MusicMainClass.class, args);
}
}
常見情況二:多模塊架構(gòu) bean 沒有被掃描

com.common.* ,而啟動(dòng)類所在的包路徑為:com.training.* ,因此子模塊中的 bean 無(wú)法被 Spring 自動(dòng)掃描到。@ComponentScan 或 ScanbasePackages 屬性,這里不過多贅述。常見情況三:使用@Qualifier 或 @Resource 注入時(shí)指定的 name 不存在
@Component、@Repository、@Service、@Controller 去把一個(gè)類配置為bean時(shí),如果不指定bean的名稱,那么 bean 的名稱的默認(rèn)規(guī)則是:類名的首字母小寫,例如:類名稱 UserDao ,那么默認(rèn)的bean名稱 userDao
如果類名前兩個(gè)(或兩個(gè)以上)連續(xù)的字母都是大寫,那么默認(rèn)的bean名稱與類名一樣,例如:類名稱 MIXDao ,那么默認(rèn)的bean名稱 MIXDao
@Bean + @Configuration 注入 bean 時(shí),如果不指定 bean 的名稱,那么 bean 的名稱默認(rèn)規(guī)則是:bean 名稱與注入的方法名同名@Autowired 注解能夠自動(dòng)注入同類型的 bean,但如果與該屬性同類型的 bean 不止一個(gè)存在時(shí),Spring 無(wú)法判斷具體注入哪個(gè) bean ,@Qualifer 注解就能夠解決這樣的歧義。@Qualifer 能夠指定 value 字段指定需要注入 bean 的名稱,通過指定名稱來(lái)指定 Spring 到底應(yīng)該注入哪一個(gè) bean ,這樣就能消除歧義,例如下面的例子:public class Teacher{
@Autowired
private Student student;
}
<bean id="teacher" class="com.test.Teacher"/>
# 下面有兩個(gè)相同類型不同 name 的 Student bean
<bean id="student1"class="com.test.Student">
<property name="name"value="zhangsan"/>
</bean>
<bean id="student2"class="com.test.Student">
<property name="name"value="lisi"/>
</bean>
@Autowired 注解產(chǎn)生了歧義,因此需要使用 @Qualifer 注解消除歧義:public class Teacher{
@Qualifer(value = "student1")
@Autowired
private Student student;
}
@Resource 注解默認(rèn)通過 名稱 進(jìn)行注入,名稱可以通過 name 屬性進(jìn)行指定,如果沒有指定name屬性,當(dāng)注解寫在字段上時(shí),默認(rèn)取字段名進(jìn)行安裝名稱查找,如果注解寫在setter方法上默認(rèn)取屬性名進(jìn)行裝配。當(dāng)找不到與名稱匹配的bean時(shí)才按照類型進(jìn)行裝配。@Qualifer 注解進(jìn)行限定。常見情況四:在攔截器或過濾器或監(jiān)聽器中注入 bean
SpringBoot + SpringSecurity 做認(rèn)證授權(quán)處理,確定注入的 bean 能夠被 Spring 掃描到,同時(shí)在 Controller、Service 層的注入也沒有問題,但是在用戶授權(quán)過濾器 UsernamePasswordAuthenticationFilter 中死活就是注入不了 bean。context-param–>listener–>filter–>servlet --> … -> Bean 的實(shí)例化
context-param–>listener–>filter–>servlet–>interceptor(指的是攔截器) --> … -> Bean 的實(shí)例化


使用 IDEA 工具查看 IOC 容器




推薦閱讀:
Jenkins+Docker 實(shí)現(xiàn)一鍵自動(dòng)化部署項(xiàng)目!步驟齊全,少走坑路
終于搞懂了 @Configuration 和 @Component 的區(qū)別
互聯(lián)網(wǎng)初中高級(jí)大廠面試題(9個(gè)G) 內(nèi)容包含Java基礎(chǔ)、JavaWeb、MySQL性能優(yōu)化、JVM、鎖、百萬(wàn)并發(fā)、消息隊(duì)列、高性能緩存、反射、Spring全家桶原理、微服務(wù)、Zookeeper......等技術(shù)棧!
?戳閱讀原文領(lǐng)?。?/span> 朕已閱


