原文地址:http://gordondickens.com/wordpress/2012/06/12/spring-3-1-environment-profiles/

Profiles

Spring 3.1 now includes support for the long awaited environment aware feature called profiles. Now we can activate profiles in our application, which allows us to define beans by deployment regions, such as “dev”, “qa”, “production”, “cloud”, etc.

We also can use this feature for other purposes: defining profiles for performance testing scenarios such as “cached” or “lazyload”.

Essential Tokens

Spring profiles are enabled using the case insensitive tokens spring.profiles.active orspring_profiles_active.

This token can be set as:

  • an Environment Variable
  • a JVM Property
  • Web Parameter
  • Programmatic

Spring also looks for the token, spring.profiles.default, which can be used to set the default profile(s) if none are specified with spring.profiles.active.

Grouping Beans by Profile

Spring 3.1 provides nested bean definitions, providing the ability to define beans for various environments:

1
2
3
4
<beans profiles="dev,qa">
  <bean id="dataSource" class="..."/>
  <bean id="messagingProvider" class="..."/>
</beans>

Nested <beans> must appear last in the file. 
Beans that are used in all profiles are declared in the outer <beans> as we always have, such as Service classes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="UTF-8"?>
       xsi:schemaLocation="http://www.springframework.org/schema/beans
 
    <bean id="businessService"
       class="com.c...s.springthreeone.business.SimpleBusinessServiceImpl"/>
 
    <beans profile="dev,qa">
        <bean id="constructorBean"
          class="com.gordondickens.springthreeone.SimpleBean"
              c:myString="Constructor Set"/>
 
        <bean id="setterBean"
          class="com.gordondickens.springthreeone.SimpleBean">
            <property name="myString" value="Setter Set"/>
        </bean>
    </beans>
 
    <beans profile="prod">
        <bean id="setterBean"
          class="com.gordondickens.springthreeone.SimpleBean">
            <property name="myString" value="Setter Set - in Production YO!"/>
        </bean>
    </beans>
</beans>

If we put a single <bean> declaration at below any nested <beans> tags we will get the exception org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'bean'.

Multiple beans can now share the same XML “id” 
In a typical scenario, we would want the DataSource bean to be called dataSource in both all profiles. Spring now allow us to create multiple beans within an XML file with the same ID providing they are defined in different <beans> sets. In other words, ID uniqueness is only enforced within each <beans> set.

Automatic Profile Discovery (Programmatic)

We can configure a class to set our profile(s) during application startup by implementing the appropriate interface. For example, we may configure an application to set different profiles based on where the application is deployed – in CloudFoundry or running as a local web application. In the web.xml file we can include an Servlet context parameter,contextInitializerClasses, to bootstrap this class:

1
2
3
4
<context-param>
  <param-name>contextInitializerClasses</param-name>
  <param-value>com.gordondickens.springthreeone.services.CloudApplicationContextInitializer</param-value>
</context-param>

The Initializer class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.gordondickens.springthreeone.services;
 
import org.cloudfoundry.runtime.env.CloudEnvironment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
 
public class CloudApplicationContextInitializer implements
  ApplicationContextInitializer<ConfigurableApplicationContext> {
     
  private static final Logger logger = LoggerFactory
    .getLogger(CloudApplicationContextInitializer.class);
 
  @Override
  public void initialize(ConfigurableApplicationContext applicationContext) {
    CloudEnvironment env = new CloudEnvironment();
    if (env.getInstanceInfo() != null) {
      logger.info("Application running in cloud. API '{}'",
        env.getCloudApiUri());
      applicationContext.getEnvironment().setActiveProfiles("cloud");
      applicationContext.refresh();
    } else {
      logger.info("Application running local");
      applicationContext.getEnvironment().setActiveProfiles("dev");
    }
  }
}

Annotation Support for JavaConfig

If we are are using JavaConfig to define our beans, Spring 3.1 includes the @Profileannotation for enabling bean config files by profile(s).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.gordondickens.springthreeone.configuration;
 
import com.gordondickens.springthreeone.SimpleBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
 
@Configuration
@Profile("dev")
public class AppConfig {
  @Bean
  public SimpleBean simpleBean() {
    SimpleBean simpleBean = new SimpleBean();
    simpleBean.setMyString("Ripped Pants");
    return simpleBean;
  }
}

Testing with XML Configuration

With XML configuration we can simply add the annotation @ActiveProfiles to the JUnit test class. To include multiple profiles, use the format @ActiveProfiles(profiles = {"dev", "prod"})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.gordondickens.springthreeone;
 
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertNull;
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@ActiveProfiles(profiles = "dev")
public class DevBeansTest {
 
  @Autowired
  ApplicationContext applicationContext;
 
  @Test
  public void testDevBeans() {
    SimpleBean simpleBean =
      applicationContext.getBean("constructorBean", SimpleBean.class);
    assertNotNull(simpleBean);
  }
 
  @Test(expected = NoSuchBeanDefinitionException.class)
  public void testProdBean() {
    SimpleBean prodBean = applicationContext.getBean("prodBean", SimpleBean.class);
    assertNull(prodBean);
  }
}

Testing with JavaConfig

JavaConfig allows us to configure Spring with or without XML configuration. If we want to test beans that are defined in a Configuration class we configure our test with the loaderand classes arguments of the @ContextConfiguration annotation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.gordondickens.springthreeone.configuration;
 
import com.gordondickens.springthreeone.SimpleBean;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
 
import static org.junit.Assert.assertNotNull;
 
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class, loader = AnnotationConfigContextLoader.class)
@ActiveProfiles(profiles = "dev")
public class BeanConfigTest {
 
  @Autowired
  SimpleBean simpleBean;
 
  @Test
  public void testBeanAvailablity() {
    assertNotNull(simpleBean);
  }
}

Declarative Configuration in WEB.XML

If we desire to set the configuration in WEB.XML, this can be done with parameters onContextLoaderListener.

Application Context

1
2
3
4
5
6
7
8
<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>/WEB-INF/app-config.xml</param-value>
</context-param>
<context-param>
  <param-name>spring.profiles.active</param-name>
  <param-value>DOUBLEUPMINT</param-value>
</context-param>

Log Results

DEBUG PropertySourcesPropertyResolver - Found key 'spring.profiles.active' in [servletContextInitParams] with type [String] and value 'DOUBLEUPMINT'

Environment Variable/JVM Parameter
Setting an environment variable can be done with either spring_profiles_default orspring_profiles_active. In Unix/Mac it would be export SPRING_PROFILES_DEFAULT=DEVELOPMENT for my local system.

We can also use the JVM “-D” parameter which also works with Maven when using Tomcat or Jetty plugins.

Note: Remember the tokens are NOT case sensitive and can use periods or underscores as separators. For Unix systems, you need to use the underscore, as above.

Logging of system level properties DEBUG PropertySourcesPropertyResolver - Found key 'spring.profiles.default' in [systemProperties] with type [String] and value 'dev,default'

Summary

Now we are equipped to activate various Spring bean sets, based on profiles we define. We can use  traditional, XML based configuration, or the features added to support JavaConfig originally introduced in Spring 3.0.

Spring 3.1 Environment Profiles--转载的更多相关文章

  1. Spring Boot Common application properties(转载)

    转自官方文档:http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.h ...

  2. spring中context:property-placeholder/元素 转载

    spring中context:property-placeholder/元素  转载 1.有些参数在某些阶段中是常量 比如 :a.在开发阶段我们连接数据库时的连接url,username,passwo ...

  3. Spring AOP详解(转载)所需要的包

    上一篇文章中,<Spring Aop详解(转载)>里的代码都可以运行,只是包比较多,中间缺少了几个相应的包,根据报错,几经百度搜索,终于补全了所有包. 截图如下: 在主测试类里面,有人怀疑 ...

  4. Spring中的Environment外部化配置管理详解

    Environment的中文意思是环境,它表示整个spring应用运行时的环境信息,它包含两个关键因素 profiles properties profiles profiles这个概念相信大家都已经 ...

  5. SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)【转载】

    最近在学习Spring+SpringMVC+MyBatis的整合.以下是参考网上的资料自己实践操作的详细步骤. 1.基本概念   1.1.Spring Spring是一个开源框架,Spring是于20 ...

  6. Spring 中JCA CCI分析--转载

    转载地址:http://blog.csdn.net/a154832918/article/details/6790612 J2EE提供JCA(Java Connector Architecture)规 ...

  7. Spring 实现动态数据源切换--转载 (AbstractRoutingDataSource)的使用

    [参考]Spring(AbstractRoutingDataSource)实现动态数据源切换--转载 [参考] 利用Spring的AbstractRoutingDataSource解决多数据源的问题 ...

  8. Junit单元测试注入spring中的bean(转载)

    转载自:http://blog.csdn.net/cy104204/article/details/51076678 一般对于有bean注入的类进行方法单元测试时,会发现bean对象并没有注入进来,对 ...

  9. SSM三大框架整合详细教程(Spring+SpringMVC+MyBatis)(转载)

    使用SSM(Spring.SpringMVC和Mybatis)已经有三个多月了,项目在技术上已经没有什么难点了,基于现有的技术就可以实现想要的功能,当然肯定有很多可以改进的地方.之前没有记录SSM整合 ...

随机推荐

  1. [原创]cocos2d-x + Lua接入iOS原生SDK的实现方案

    相信很多朋友在使用cocos2d-x+lua开发游戏时都遇到过接入iOS原生SDK的问题,比如常见的接应用内支付SDK,广告SDK或是一些社交平台SDK等等,我也没少接过这类SDK.这篇文章主要是对我 ...

  2. C++11 之 " = delete "

    1  缺省函数 设计一个类,没有成员函数 (member function),只有成员数据 (member data) class DataOnly { private: std::string st ...

  3. oc_转_NSArrray 和 NSMutableArrray

    Objective C 中除了可以使用C中的基本数组外,如 int[5];,char word[] = {‘a’, 'b’, 'c’};,Foundation 还提供了 NSArray 类.Found ...

  4. Javascript原理

    1.javascript创建对象 创建新对象有两种不同的方法: 定义并创建对象的实例 person=new Object(); person.firstname="Bill"; p ...

  5. SRM 511 DIV1 500pt(DP)

    题目简述 给定n个数,两个人轮流取数,和之前两个人的取的数或起来,谁不能取数或者谁取到的数和之前的数或值为511谁输,问谁能够赢? 题解 刚开始的想法是直接搜,不过需要记录取过的值的状态,2^50显然 ...

  6. 生成chm文档工具- Sandcastle -摘自网络

    Sandcastle是微软官方的文档生成工具,NDoc开发停止后,这个貌似也是唯一的一个这方面的工具.它从dll文件及其xml注释文件能够 生成完整的帮助文档,支持多种生成格式(Helpe1x:chm ...

  7. ES6学习(1)——如何通过babel将ES6转化成ES5

    使用babel编译ES6 babel是一个工具,可以通过多个平台,让js文件从ES6转化成ES5,从而支持一些浏览器并未支持的语法. Insall babel $ sudo npm install b ...

  8. Java邮件服务学习之二:SMTP和POP3

    一.SMTP SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则.SMTP协议属于TCP/IP协议簇,它帮助每台计算 ...

  9. hdu 5363 Key Set

    http://acm.hdu.edu.cn/showproblem.php?pid=5363 Key Set Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  10. poj 1543 Perfect Cubes(注意剪枝)

    Perfect Cubes Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14901   Accepted: 7804 De ...