在之前我們就Swagger使用篇,可以了解到根據不同環境更改為不同的配置,讓不同的配置邏輯生效的處理辦法。其實吧,有沒有覺得這東西就像是一個開關,那么SpringBoot 我們可以怎么獲取當前環境(獲取其他配置相同)從而進行判斷做一個開關呢?今天我們就來總結下(以下列舉的是常用的幾種方式):
方式一:@Value 注解
代碼如下(基本容器啟動什么地方都可以用):
@RestController
@RequestMapping("/test")
public class TestController {
@Value("${spring.profiles.active}")
String active;
@GetMapping("hello")
public String sayHello(){
return "hello, active env is: ["+active+"]";
}
}
方式二:Spring 配置上下文
代碼如下(啟動時獲取):
@SpringBootApplication
public class SpringStudyApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringStudyApplication.class, args);
String active = context.getEnvironment().getProperty("spring.profiles.active");
System.out.println(">>>>>>>>>>>>>>>>>>>>> active env is: ["+active+"]");
// FileHelper.xmlName = active+".xml";
// FileHelper.ReaderXml();
}
}
題外話:現在用了springBoot 后各種簡化了的配置,properties,yaml;那你還寫xml 嗎?
個人覺得如果配置多了,yaml 和properties 的這種配置反而有點不直觀(一行就可以寫清楚的,一直往下點很多個...),可能還是得用一些xml 配置;當然不用也不是不可以,比如你們用了Apollo 自動配置,那實時修改不用發包就能生效,肯定所有的配置都整成yaml 格式的要好啊!
但是xml配置我們也得知道,看如下代碼讀取xml 配置文件並組裝成key,value使用;對應的環境配置也可以從此處讀取
引入dom4j依賴:
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
在resources下新增文件夾configuration,新增配置文件dev.xml
<?xml version = "1.0" encoding="UTF-8"?>
<system>
<config name="env-context" explain="環境相關">
<item name="active" value="dev" explain="dev 環境"/>
</config>
<config name="def-config" explain="自定義配置">
<item name="host" value="xxx.xxx.xxx.xxx" explain="主機ip"/>
<item name="port" value="22" explain="端口號"/>
<item name="account" value="root" explain="賬號"/>
<item name="password" value="123456" explain="密碼"/>
</config>
</system>
添加工具讀取配置文件FileHelper類:
public class FileHelper {
public static String xmlName = "";
public static final Map<String,String > map = new HashMap<String, String>();
public static void ReaderXml(){
// 創建SAXReader的對象reader
SAXReader reader = new SAXReader();
ResourceLoader resourceLoader = new DefaultResourceLoader();
String name = "";
String key = "";
try {
// 通過reader對象的read方法加載configuration.xml文件,獲取docuemnt對象。
File file = new File(xmlName);
Resource resource = new FileSystemResource(file);
if (!resource.exists()) {
//jar同級目錄加載目錄下還是找不到,那就直接用classpath下的
resource = resourceLoader.getResource("classpath:configuration/"+xmlName);
}
Document document = reader.read(resource.getInputStream());
// 通過document對象獲取根節點bookstore
Element bookStore = document.getRootElement();
// 通過element對象的elementIterator方法獲取迭代器
Iterator it = bookStore.elementIterator();
// 遍歷迭代器
String keyName = "name";
String keyValue = "value";
while (it.hasNext()) {
Element str = (Element) it.next();
// 獲取屬性名以及屬性值
List<Attribute> strAttrs = str.attributes();
for (Attribute attr : strAttrs) {
if(attr.getName().equals(keyName)){
name = attr.getValue();
}
}
//解析子節點的信息
Iterator itt = str.elementIterator();
while (itt.hasNext()) {
Element strChild = (Element) itt.next();
List<Attribute> bookChildList = strChild.attributes();
for (Attribute attr : bookChildList) {
if(attr.getName().equals(keyName)){
key = name +"." + attr.getValue();
}
if(attr.getName().equals(keyValue)){
map.put(key,attr.getValue());
}
}
}
}
System.out.println(">>>>>>>>>>>>>>>>讀取配置文件內容如下:"+map);
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 重新加載xml配置文件
* @return
*/
public static Map<String,String> RestReaderXml(){
map.clear();
ReaderXml();
return map;
}
}
讀取配置文件內容如下:{def-config.account=root, def-config.host=xxx.xxx.xxx.xxx, def-config.password=123456, env-context.active=dev, def-config.port=22}
那么,我們就可以根據對應的key 獲取對應的配置了。
方式三:自定義SpringContextUtil工具類
代碼如下:
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext context = null;
/* (non Javadoc)
* @Title: setApplicationContext
* @Description: spring獲取bean工具類
* @param applicationContext
* @throws BeansException
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.context = applicationContext;
}
// 傳入線程中
public static <T> T getBean(String beanName) {
return (T) context.getBean(beanName);
}
// 國際化使用
public static String getMessage(String key) {
return context.getMessage(key, null, Locale.getDefault());
}
/// 獲取當前環境
public static String getActiveProfile() {
return context.getEnvironment().getActiveProfiles()[0];
}
}
方式四:Environment 類
代碼如下(在bean中使用,例如之前Swagger 的配置,其實只要初始化配置能夠讀到的地方都可以這樣用):
Profiles pro = Profiles.of("dev","test");
// 判斷是否是對應的環境
boolean enable = env.acceptsProfiles(pro);
詳見之前的博客:Swagger食用方法詳解
