SpringBoot 中的那些“開關”


在之前我們就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食用方法詳解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM