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注釋的必須為接口類,否則將會報錯