本節書摘來自異步社群《spring實戰(第4版)》一書中的第2章,第2.5節,作者: 【美】craig walls(沃爾斯)著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
在典型的spring應用中,我們可能會同時使用自動化和顯式配置。即便你更喜歡通過javaconfig實作顯式配置,但有的時候xml卻是最佳的方案。
幸好在spring中,這些配置方案都不是互斥的。你盡可以将javaconfig的元件掃描和自動裝配和/或xml配置混合在一起。實際上,就像在2.2.1小節中所看到的,我們至少需要有一點顯式配置來啟用元件掃描和自動裝配。
關于混合配置,第一件需要了解的事情就是在自動裝配時,它并不在意要裝配的bean來自哪裡。自動裝配的時候會考慮到spring容器中所有的bean,不管它是在javaconfig或xml中聲明的還是通過元件掃描擷取到的。
你可能會想在顯式配置時,比如在xml配置和java配置中該如何引用bean呢。讓我們先看一下如何在javaconfig中引用xml配置的bean。
2.5.1 在javaconfig中引用xml配置
現在,我們臨時假設cdplayerconfig已經變得有些笨重,我們想要将其進行拆分。當然,它目前隻定義了兩個bean,遠遠稱不上複雜的spring配置。不過,我們假設兩個bean就已經太多了。
我們所能實作的一種方案就是将blankdisc從cdplayerconfig拆分出來,定義到它自己的cdconfig類中,如下所示:

compactdisc()方法已經從cdplayerconfig中移除掉了,我們需要有一種方式将這兩個類組合在一起。一種方法就是在cdplayerconfig中使用@import注解導入cdconfig:
或者采用一個更好的辦法,也就是不在cdplayerconfig中使用@import,而是建立一個更進階别的soundsystemconfig,在這個類中使用@import将兩個配置類組合在一起:
不管采用哪種方式,我們都将cdplayer的配置與blankdisc的配置分開了。現在,我們假設(基于某些原因)希望通過xml來配置blankdisc,如下所示:
現在blankdisc配置在了xml之中,我們該如何讓spring同時加載它和其他基于java的配置呢?
答案是@importresource注解,假設blankdisc定義在名為cd-config.xml的檔案中,該檔案位于根類路徑下,那麼可以修改soundsystemconfig,讓它使用@importresource注解,如下所示:
兩個bean——配置在javaconfig中的cdplayer以及配置在xml中blankdisc——都會被加載到spring容器之中。因為cdplayer中帶有@bean注解的方法接受一個compactdisc作為參數,是以blankdisc将會裝配進來,此時與它是通過xml配置的沒有任何關系。
讓我們繼續這個練習,但是這一次,我們需要在xml中引用javaconfig聲明的bean。
2.5.2 在xml配置中引用javaconfig
假設你正在使用spring基于xml的配置并且你已經意識到xml逐漸變得無法控制。像前面一樣,我們正在處理的是兩個bean,但事情實際上會變得更加糟糕。在被無數的尖括号淹沒之前,我們決定将xml配置檔案進行拆分。
在javaconfig配置中,我們已經展現了如何使用@import和@importresource來拆分javaconfig類。在xml中,我們可以使用import元素來拆分xml配置。
比如,假設希望将blankdisc bean拆分到自己的配置檔案中,該檔案名為cd-config.xml,這與我們之前使用@importresource是一樣的。我們可以在xml配置檔案中使用元素來引用該檔案:
現在,我們假設不再将blankdisc配置在xml之中,而是将其配置在javaconfig中,cdplayer則繼續配置在xml中。基于xml的配置該如何引用一個javaconfig類呢?
事實上,答案并不那麼直覺。元素隻能導入其他的xml配置檔案,并沒有xml元素能夠導入javaconfig類。
但是,有一個你已經熟知的元素能夠用來将java配置導入到xml配置中:元素。為了将javaconfig類導入到xml配置中,我們可以這樣聲明bean:
采用這樣的方式,兩種配置——其中一個使用xml描述,另一個使用java描述——被組合在了一起。類似地,你可能還希望建立一個更高層次的配置檔案,這個檔案不聲明任何的bean,隻是負責将兩個或更多的配置組合起來。例如,你可以将cdconfig bean從之前的xml檔案中移除掉,而是使用第三個配置檔案将這兩個組合在一起:
不管使用javaconfig還是使用xml進行裝配,我通常都會建立一個根配置(root configuration),也就是這裡展現的這樣,這個配置會将兩個或更多的裝配類和/或xml檔案組合起來。我也會在根配置中啟用元件掃描(通過或@componentscan)。你會在本書的很多例子中看到這種技術。