在實際開發中,開發人員在編寫springboot的時候通常要在本地環境測試然后再部署到production環境,這兩種環境一般來講是不同的,最主要的區別就是數據源的不同。
在應用環境中,集成在容器的抽象環境模型有兩個方面:profiles和properties。只有給出的profile被激活,一組邏輯命名的bean定義才會在容器中注冊。
環境變量對象角色和profiles的關系來決定哪個profiles(如果有)處于當前激活狀態,哪個profiles默認被激活。
@profile
基于java類的環境配置
@profile注解可以用來標注@configuration注解的類。表示該特定環境下激活該類下的所有bean。當然也可以專門用來標注@bean,因為許多時候本地環境和production環境的區別只是數據源不同罷了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@configuration public class profileconf { @bean @profile ( "dev" ) public userinfo devuserinfo() { userinfo userinfo = new userinfo(); userinfo.setid( 1 ); userinfo.setname( "dev" ); return userinfo; } @bean @profile ( "production" ) public userinfo productionuserinfo() { userinfo userinfo = new userinfo(); userinfo.setid( 1 ); userinfo.setname( "production" ); return userinfo; } } |
激活profile
現在我們已經更新了我們的配置,我們仍然需要說明哪個profile是激活的。如果直接注冊@configuration標注的類,這將會看到一個nosuchbeandefinitionexception被拋出,因為容器找不到一個對應的環境下的bean。
1
2
3
4
5
6
7
|
public static void main(string[] args) { annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(); context.getenvironment().setactiveprofiles( "dev" ); context.register(userconf. class ); context.refresh(); system.out.println(context.getbean(userinfo. class )); } |
默認的profile
默認配置文件表示默認啟用的配置文件。
1
2
3
4
5
6
7
8
|
@bean @profile ( "default" ) public userinfo defaultuserinfo() { userinfo userinfo = new userinfo(); userinfo.setid( 1 ); userinfo.setname( "default" ); return userinfo; } |
如果沒有profile是激活狀態,上面的bean將會被創建;這種方式可以被看做是對一個或者多個bean提供了一種默認的定義方式。如果啟用任何的profile,那么默認的profile都不會被應用。
屬性源抽象
spring 環境抽象提供了可配置的屬性源層次結構的搜索操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public static void main(string[] args) { annotationconfigapplicationcontext context = new annotationconfigapplicationcontext(); // context.getenvironment().setactiveprofiles("dev"); context.getenvironment().setactiveprofiles( "dev" ); context.register(profileconf. class ); context.refresh(); configurableenvironment environment = context.getenvironment(); map<string, object> maps = environment.getsystemproperties(); maps.keyset().foreach(k -> system.out.println(k + "->" + maps.get(k))); system.out.println( "===========================" ); map<string, object> environment1 = environment.getsystemenvironment(); environment1.keyset().foreach(k -> system.out.println(k + "->" + environment1.get(k))); system.out.println(environment.containsproperty( "java.vm.version" )); } |
在上面的例子中可以獲取environment的兩個系統變量以及環境變量。
一個propertysource是對任何key-value資源的簡單抽象,并且spring 的標準環境是由兩個propertysource配置的,一個表示一系列的jvm 系統屬性(system.getproperties()),一個表示一系列的系統環境變量(system.getenv())。
具體的說,當使用standardenvironment時,如果在運行時系統屬性或者環境變量中包括foo,那么調用env.containsproperty(“java.vm.version”)方法將會返回true。
更重要的是,整個機制都是可配置的。也許你有個自定義的屬性來源,你想把它集成到這個搜索里面。這也沒問題,只需簡單的實現和實例化自己的propertysource,并把它添加到當前環境的propertysources集合中:
1
2
3
|
configurableapplicationcontext ctx = new genericapplicationcontext(); mutablepropertysources sources = ctx.getenvironment().getpropertysources(); sources.addfirst( new mypropertysource()); |
@propertysource
上一篇文章講到,基于java的配置很多時候會和xml混合使用。其中@import還可以導入其他java配置類,這里要說的@propertysource注解表示導入.properties文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
@configuration @propertysource ( "classpath:user.properties" ) public class userconf { @autowired environment environment; @bean //每次調用就創建一個新的bean @scope ( "prototype" ) public userinfo userinfo() { userinfo userinfo = new userinfo(); userinfo.setid(integer.valueof(environment.getproperty( "user.id" ))); system.out.println(environment.getproperty( "user.name" )); userinfo.setname(environment.getproperty( "user.name" )); return userinfo; } } |
1
2
|
user.id= 11 user.name=asdasd |
任何出現在@propertysource中的資源位置占位符都會被注冊在環境變量中的資源解析。
假設”user.name”已經在其中的一個資源中被注冊,例如:系統屬性或環境變量,占位符將會被正確的值解析。
如果沒有,”default/path”將會使用默認值。如果沒有默認值,而且無法解釋屬性,則拋出illegalargumentexception異常。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。