美文网首页
Spring 环境变量动态读取

Spring 环境变量动态读取

作者: caobug | 来源:发表于2016-06-26 01:53 被阅读4974次

我们的项目通常会发布在不同的系统、不同的受众环境提供外部或内部访问,如:内测、公测、生产环境、基于 WIN/LINUX等。发布至不同的环境,我们通常会配置不同的数据库账户密码、连接数、生成测试数据等。如果没有一套固定的机制自动配置,而在发布时手工修改,犯错率不仅很大,同时效率也很低。

程序员的优点是懒,缺点是不够懒。O(∩_∩)O哈哈哈~

以下分为 Spring App 和 Spring MVC 两种场景介绍,目的是打包前改一个变量,它能自动读取对应配置。如 env = prod

先创建一个 MyProperties 用于装载属性 key/value:

package com.caobug.demo.springenv;

/**
 * 属性
 * <p>
 * Created by caobug on 16/6/26.
 *
 * @author caobug
 * @since 1.7
 */
public class MyProperties {

    private String ipAddress;
    private String username;
    private String password;

    public String getIpAddress() {
        return ipAddress;
    }

    public void setIpAddress(String ipAddress) {
        this.ipAddress = ipAddress;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "MyProperties{" +
                "ipAddress='" + ipAddress + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

再创建配置文件spring-config.xml用于关联不同环境的配置。这里可以灵活变通为读取某个配置文件或直接注入。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <beans profile="developer">
        <bean id="myProperties" class="com.caobug.demo.springenv.MyProperties">
            <property name="username" value="a"/>
            <property name="ipAddress" value="192.168.1.2"/>
            <property name="password" value="123456"/>
        </bean>
    </beans>

    <beans profile="production">
        <bean id="myProperties" class="com.caobug.demo.springenv.MyProperties">
            <property name="username" value="b"/>
            <property name="ipAddress" value="192.168.1.3"/>
            <property name="password" value="654321"/>
        </bean>
    </beans>

</beans>

以上代码和平时的依赖注入没什么差别,仅仅是多了属性 profile="developer",他用于告诉 Spring 这需要特定环境才生效。这里还有一种写法是把以下片段:

<beans xmlns="http://www.springframework.org/schema/beans"

替换为:

<beans profile="developer" xmlns="http://www.springframework.org/schema/beans"

这样做之后将需要创建不同的XML文件,环境一多就不好维护了。

我们用JUNIT验证下我们的做法:

package com.caobug.demo.springenv;

import org.junit.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by caobug on 16/6/26.
 *
 * @author caobug
 * @since 1.7
 */
public class MyPropertiesTest {

    @Test(expected = NoSuchBeanDefinitionException.class)
    public void notFound() throws Exception {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
        // ctx.getEnvironment().setActiveProfiles("developer");
        // ctx.refresh();
        MyProperties myProperties = ctx.getBean("myProperties", MyProperties.class);
        System.out.println("developer myProperties = " + myProperties);
    }

    @Test
    public void developer() throws Exception {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
        ctx.getEnvironment().setActiveProfiles("developer");
        ctx.refresh();
        MyProperties myProperties = ctx.getBean("myProperties", MyProperties.class);
        System.out.println("developer myProperties = " + myProperties);
    }

    @Test
    public void production() throws Exception {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
        ctx.getEnvironment().setActiveProfiles("production");
        ctx.refresh();
        MyProperties myProperties = ctx.getBean("myProperties", MyProperties.class);
        System.out.println("production myProperties = " + myProperties);
    }
}

我们需要特别注意的是,如果我们没有为ctx设定对应的环境(developer or production),或者有设定但未调用ctx.refresh();时,若尝试获取bean将会抛出NoSuchBeanDefinitionException异常,请参考以上notFound()测试方法。

楼上说:想RUN就RUN!不管了,我们再来看下 Spring MVC 中如何配置:

相关文章

网友评论

      本文标题:Spring 环境变量动态读取

      本文链接:https://www.haomeiwen.com/subject/twvadttx.html