spring為何要注入接口,而注入接口的實現類就會報錯


Spring的注入包括@Resource和@Autowired

@Resource

這里的接口類如果只是注入也可以為實現類。單為什么用接口類呢?是因為: 

往往開發中會對實現類做增強,如事務,日志等,實現增強的AOP技術是通過動態代理實現的,而spring默認是JDK動態代理,對實現類對象做增強得到的增強類與實現類是兄弟關系,所以不能用實現類接收增強類對象,只能用接口接收。如:

//接口:IUser

//實現類:UserImpl

//增強類:UserProxy

UserImpl userImpl= new UserImpl();

//通過JDKProxyFactory創建代理對象
JDKProxyFactory factory = new JDKProxyFactory(userImpl);
UserProxy userProxy= factory.createProxy();

這個增強類對象userProxy只能強轉為IUser,而不能轉為UserImpl,因為JDK代理得到的UserProxy 類與UserImpl是兄弟關系而非父子

由於以上原因,如果將對象注入給實現類而非接口的話,在代理時就會報錯。

 解決方法

讓Spring強制使用Cglib代理:(不推薦)

<aop:aspectj-autoproxy proxy-target-class="true"/>

cglib代理類和實現類之間是父子關系,自然可以用父類(實現類)去接收子類對象(代理類對象即增強類對象)。

總結

其實這篇文章這個問題感覺好可笑,為啥用接口?用習慣了唄,但是底層的實現很多人都不知道。使接口本來就是解耦的,還記得java的三大特性嗎?- 封裝,繼承和多態。如果直接實現類,是不是與初衷相違背?

鏈接:https://www.jianshu.com/p/50cd53040130

@Autowired

@Autowired默認按byType注入:尋找實現了interface的Bean,適用於只有一個Bean實現了接口的情況。

所以在默認情況下@Autowired注釋的必須為接口類,否則將會報錯

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM