1、原因分析
1.1 包沒(méi)有被掃描到菱皆;
通過(guò)@Autowired注入的類所在的包路徑不在Application啟動(dòng)類所在的包/子包路徑下。
Spring Boot項(xiàng)目的Bean裝配默認(rèn)規(guī)則是根據(jù)Application類(指項(xiàng)目入口類)所在的包位置從上往下掃描。
eg: Application啟動(dòng)類在包c(diǎn)om.alibaba.taobao下拯田,則只會(huì)掃描com.alibaba.taobao包及其所有子包甩十,如果需要自動(dòng)裝載的類所在包不在com.alibaba.taobao及其子包下,而是在com.alibaba.tmall下侣监,則不會(huì)被掃描,自然就沒(méi)法被注入窃爷!
1.2 代碼中使用new關(guān)鍵字創(chuàng)建實(shí)例按厘;
若類A中包含成員屬性B, B是通過(guò)@Autowired自動(dòng)注入钱慢,而類A的實(shí)例是通過(guò)new的方式產(chǎn)生,則自動(dòng)注入會(huì)失效的束莫。
2、針對(duì)上述的解決方法
2.1 添加包掃描
在啟動(dòng)類中定義分別掃描兩個(gè)包 策严,即在@SpringBootApplication注解的類中添加:
@ComponentScan({"com.alibaba.taobao","com.alibaba.tmall"})
或
@ComponentScan({"com.alibaba"})
2.2 通過(guò)Spring上下文工具類獲取bean
定義一個(gè)SpringUtil類
/**
* Spring上下文工具類享钞,用以讓普通類獲取Spring容器中的Bean
*/
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
//獲取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
//通過(guò)name獲取 Bean
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
}
然后在類A中通過(guò)如下調(diào)用獲取Spring容器中的B實(shí)例
ClassBInterface b = (ClassBInterfaceImpl) SpringUtil.getBean("classBInterfaceImpl");