天天看點

spring的Profile使用對比和應用場景分析

spring中存在這樣一個功能,通過profile來選擇不同環境下的不同配置,說白了,就是通過設定一個參數來選擇使用不同的資料,這個資料可能是一個bean,可能是一個xml檔案,也有可能是一個propertes檔案。

經過代碼演練和測試,我大體知道了這個功能是幹嘛的,也初步知道了它的幾種實作方式,但是實際上我依然不是十分明白它的優勢和好處在何處,因為根據自己以往的項目經驗來說,我覺得用這種方式似乎還有點把簡單功能複雜化了。

隻是,在網絡上我不止一次看到過它,似乎很多人都在用。是以我覺得還是了解一下、學習一下為好,或許它的好處隻是我暫時不清楚,而不代表這個好處不存在。

為了讓剛接觸的朋友能更好的了解,我這裡基本上都是代碼和測試都寫出來,并且三種方式簡單的對比,以便于在大家需要用到的時候能具體場景下具體的選擇。

實作方式一

完全的java代碼加注解的方式,首先建立一個簡單的帶有構造方法和get、set方法的類:

然後再建立一個相當于spring中xml配置檔案的類,并且使用注解把這個類聲明成一個配置類,同時把上邊的類聲明為一個bean,并制定profile名稱(也就是上邊說的profile的選擇參數):

這裡的@configuration即聲明這個類是一個相當于spring中xml的配置類,剩下兩個在前一段文字描述中已經說了,就不再贅述。

至于這段代碼的解釋,我想通過下邊調用的測試代碼之後再做解釋,模拟profile調用的main方法如下:

這裡的new annotationconfigapplicationcontext()聲明一個空的上下文,我想學過spring的應該都不需要解釋。

context.getenvironment().setactiveprofiles(“test2”)的意思是擷取環境變量,或者了解成擷取配置資料,然後把活動的profile的參數或者說名稱設定成test2。

context.register(profileconf.class)注冊具體的配置檔案,這裡就是profilecon.class。

然後後邊的幾行代碼分别是重新整理上下文,擷取具體的bean對象等等,這些就是比較正常的操作了。

上面的方法執行後結果如圖:

spring的Profile使用對比和應用場景分析

而當我把context.getenvironment().setactiveprofiles(“test2”)這裡的test2設定成test1的時候,結果就會成為test11111。

那麼結合上邊的profileconf 中的代碼,我想就比較容易了解了,也就是說這裡配置了profile參數後,當我們把activeprofiles設定成某個參數時,spring在加載時便會調用這個參數對應的profile的内容。

但是為什麼我要說看不出來這樣使用的好處在哪裡呢?是因為我覺得就這個例子來說,完全可以直接在建立新的對象時用構造方法的不同參數來實作。

當然了,這隻是個為了說明這項功能的例子,實際使用自然不會這樣,實際使用的時候,可能是用來加載不同的配置檔案裡的值和屬性,也可能是用來調用不同的配置檔案。

隻不過,即便是這樣,我依舊覺得也都可以用參數的方式實作,似乎沒有必要這樣繞來繞去,并沒看到怎麼簡化了開發,也沒看到有什麼性能上的提升。

那麼還有實作方式二

這個方式和上邊的其實是類似的,因為唯一的不同在于把起xml配置檔案作用的java類實打實的變成xml配置,因為使用的有構造方法和get、set方法的類是同一個,是以就不再重複貼出來,這裡就從test1.xml開始:

這也是一個極其簡單的spring配置,除開必要的檔案頭尾,就隻有兩個幾乎一模一樣的beans,指定了profile名稱,以及内部的一個普通bean,這個bean以構造函數注入。

對于這種寫法,調用也基本是一樣的,隻不過context擷取的是xml而不是calss:

至于這裡的具體說明,我想通過對第一個例子的解釋,應該已經沒有必要再多說了。

實作方式三

前邊兩種方式,根本上來說是改變了profile的聲明方式,而這裡需要變得則是調用方式,前兩個抛開細節來說,都是在java類中調用,而這裡則是在web.xml中調用,當然了,既然有web.xml檔案,自然也要是一個web項目才行,web.xml檔案配置如下:

這個web.xml也是一個隻為了說明profile的檔案,隻要一個selvlet配置,兩個init-param,第一個是指定自定義的dispatcher-servlet.xml,如果不指定,啟動tomcat的時候就會出現如下的錯誤:

而第二個init-param則是指定預設的profile的名稱。

為了測試這種方式是否可行,我在第二種方式的基礎上略作了修改,java類中加入了一個init-method方法,修改之後對應的java類和xml配置如下:

啟動tomcat的過程中,控制台也列印出了預想中的資料,證明第三種方式也是可行的。

以上便是我所知道的三種profile的實作方式,至于具體應用場景,我雖然知道主要是為了友善各種不同環境的切換。比如生産一套配置,測試一套配置;再比如一套單機環境,一套叢集環境等等,但是我都覺得完全可以在部署的時候,在spring的context:property-placeholder以及import resource的時候切換。

而且這種切換比起profile來說似乎更加容易上手,是以就不太明白profile的優勢究竟在于哪裡,歡迎朋友們留言解惑。