Spring 环境变量动态读取

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

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

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

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

package com.caobug.demo.springenv;

/**
 * 属性
 * 

* 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用于关联不同环境的配置。这里可以灵活变通为读取某个配置文件或直接注入。




    
        
            
            
            
        
    

    
        
            
            
            
        
    


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

替换为:

这样做之后将需要创建不同的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 环境变量动态读取)