最近在工作中遇到這個問題,在抽象類中使用Autowired這個注解,注入mybatis的dao時,總是出現空指針異常,通過日志的打印,發現是這個dao注入失敗為空。然后通過new出spring上下文對象,再去調用getBean()方法,獲取到這個注入的dao,這樣是可行的,但是總是覺得這不是最佳實踐,一定有比這個更加優雅的方式能解決這個問題。
我們來還原一下這個問題:
1.定義一個抽象類,聲明為spring組件,在其中自動裝配另一個bean:
1 @Component 2 public abstract class BaseService { 3 @Autowired 4 Dao dao; 5 }
2.然后在他的子類中使用這個自動裝配的對象:
1 @Component 2 public class myService extends BaseService{ 3 public void print(){ 4 //運行時為null 5 System.out.print(dao.toString()); 6 } 7 }
在我們實例化子類對象的時候,抽象父類不能實例化,因為spring注入的是實例對象,而不是類,所以spring不會將dao自動裝配注入到一個實例中。但是我們通過在在抽象類中獲取的上下文對象中卻可以拿到dao,因為這個上下文對象
是我們自己手動new出來的,不是spring通過反射注入到對象中去的。因此這種方案是可行的。
下面介紹一種更優雅的解決方案:
1.同樣是定義一個抽象類;
1 public class BaseService { 2 Dao dao; 3 }
2.在子類中使用注解:
@Component public class myService extends BaseService{ //Autowired修飾方法時,根據方法參數類型判斷實例化哪個類 @Autowired public void printDao(Dao dao){ super.dao = dao;//父類屬性注入 } public void print(){ System.out.print(dao.toString()); } }
這樣寫是不是要比我們直接去new applicationContext更加優雅呢?