1、激活Profile的几种方式
Spring通过两个不同属性来决定哪些profile可以被激活(注意:profile是可以同时激活多个的),一个属性是spring.profiles.active和spring.profiles.default。这两个常量值在Spring的AbstractEnvironment中有定义,查看AbstractEnvironment源码:
/**
* Name of property to set to specify active profiles: {@value}. Value may be comma
* delimited.
* <p>Note that certain shell environments such as Bash disallow the use of the period
* character in variable names. Assuming that Spring's {@link SystemEnvironmentPropertySource}
* is in use, this property may be specified as an environment variable as
* {@code SPRING_PROFILES_ACTIVE}.
* @see ConfigurableEnvironment#setActiveProfiles
*/
public static final String ACTIVE_PROFILES_PROPERTY_NAME = "spring.profiles.active";
/**
* Name of property to set to specify profiles active by default: {@value}. Value may
* be comma delimited.
* <p>Note that certain shell environments such as Bash disallow the use of the period
* character in variable names. Assuming that Spring's {@link SystemEnvironmentPropertySource}
* is in use, this property may be specified as an environment variable as
* {@code SPRING_PROFILES_DEFAULT}.
* @see ConfigurableEnvironment#setDefaultProfiles
*/
public static final String DEFAULT_PROFILES_PROPERTY_NAME = "spring.profiles.default";
如果当spring.profiles.active属性被设置时,那么Spring会优先使用该属性对应值来激活Profile。当spring.profiles.active没有被设置时,那么Spring会根据spring.profiles.default属性的对应值来进行Profile进行激活。如果上面的两个属性都没有被设置,那么就不会有任务Profile被激活,只有定义在Profile之外的Bean才会被创建。我们发现这两个属性值其实是Spring容器中定义的属性,而我们在实际的开发中很少会直接操作Spring容器本身,所以如果要设置这两个属性,其实是需要定义在特殊的位置,让Spring容器自动去这些位置读取然后自动设置,这些位置主要为如下定义的地方:
作为SpringMVC中的DispatcherServlet的初始化参数(initParam),如:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>spring.profiles.active</param-name>
<param-value>development</param-value>
</init-param>
</servlet>
作为Web 应用上下文中的初始化参数,如:
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>production</param-value>
</context-param>
作为JNDI的入口
作为环境变量,如:
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext();
// 在配置类中通过@Profile("production")注解或在配置文件中通<beans profile="production">定义的一系列Bean可以被实例化
context.getEnviroment().setActiveProfiles("production");
// 注册配置类
context.register(ProfileConfig.class);
context.refresh();
作为虚拟机的系统参数
使用@AtivceProfile来进行激活
我们在实际的使用过程中,可以定义默认的profile为开发环境,当实际部署的时候,主需要在实际部署的环境服务器中将spring.profiles.active定义在环境变量中来让Spring自动读取当前环境下的配置信息,这样就可以很好的避免不同环境而频繁修改配置文件的麻烦。
2、举例说明
2.1、普通Bean
package com.profile;
public class DemoBean {
private String content;
public DemoBean(String content) {
super();
this.content = content;
}
public void setContent(String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void testContent() {
System.out.println("Content is " + content);
}
}
2.2、Configuration类
package com.profile;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
@ComponentScan("com.profile")
public class ProfileConfig {
@Bean
@Profile("development")
public DemoBean devDemoBean() {
return new DemoBean("I am a development bean.");
}
@Bean
@Profile("production")
public DemoBean proDemoBean() {
return new DemoBean("I am a production bean.");
}
}
2.3、测试类
package com.profile;
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;
//使用spring的test类代替Junit4测试类
@RunWith(SpringJUnit4ClassRunner.class)
//通过配置类加载配置用于测试的ApplicationContext
@ContextConfiguration(classes=ProfileConfig.class)
//激活相应的profile,此处可修改为配置类ProfileConfig中Bean 对应的@Profile("XXX")的XXX
@ActiveProfiles("production")
public class Test {
@Autowired
DemoBean demoBean;
@org.junit.Test
public void sayHello() {
demoBean.testContent();
}
}