前言本文从如下3方面探讨Spring的ProfileSpring中的Profile是什么为什么要使用Profile如何使用Profile1.Spring中的Profile 是什么Spring中的Profile功能其实早在Spring 3.1的版本就已经出来它可以理解为我们在Spring容器中所定义的Bean的逻辑组名称只有当这些Profile被激活的时候才会将Profile中所对应的Bean注册到Spring容器中。举个更具体的例子我们以前所定义的Bean当Spring容器一启动的时候就会一股脑的全部加载这些信息完成对Bean的创建而使用了Profile之后它会将Bean的定义进行更细粒度的划分将这些定义的Bean划分为几个不同的组当Spring容器加载配置信息的时候首先查找激活的Profile然后只会去加载被激活的组中所定义的Bean信息而不被激活的Profile中所定义的Bean定义信息是不会加载用于创建Bean的。2.为什么要使用Profile由于我们平时在开发中通常会出现在开发的时候使用一个开发数据库测试的时候使用一个测试的数据库而实际部署的时候需要一个数据库。以前的做法是将这些信息写在一个配置文件中当我把代码部署到测试的环境中将配置文件改成测试环境当测试完成项目需要部署到现网了又要将配置信息改成现网的真的好烦。。。而使用了Profile之后我们就可以分别定义3个配置文件一个用于开发、一个用户测试、一个用户生产其分别对应于3个Profile。当在实际运行的时候只需给定一个参数来激活对应的Profile即可那么容器就会只加载激活后的配置文件这样就可以大大省去我们修改配置信息而带来的烦恼。3.配置Spring profile在介绍完Profile以及为什么要使用它之后下面让我们以一个例子来演示一下Profile的使用这里还是使用传统的XML的方式来完成Bean的装配。3.1 例子需要的Maven依赖由于只是做一个简单演示因此无需引入Spring其他模块中的内容只需引入核心的4个模块测试模块即可。properties project.build.sourceEncodingUTF-8/project.build.sourceEncoding !--指定Spring版本该版本必须等于3.1-- spring.version4.2.4.RELEASE/spring.version !--指定JDK编译环境-- java.version1.7/java.version /properties dependencies dependency groupIdorg.springframework/groupId artifactIdspring-core/artifactId version${spring.version}/version /dependency dependency groupIdorg.springframework/groupId artifactIdspring-beans/artifactId version${spring.version}/version /dependency dependency groupIdorg.springframework/groupId artifactIdspring-context/artifactId version${spring.version}/version /dependency dependency groupIdorg.springframework/groupId artifactIdspring-expression/artifactId version${spring.version}/version /dependency dependency groupIdorg.springframework/groupId artifactIdspring-test/artifactId version${spring.version}/version scopetest/scope /dependency dependency groupIdjunit/groupId artifactIdjunit/artifactId version4.12/version scopetest/scope /dependency /dependencies build plugins plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId version2.3.2/version configuration source${java.version}/source target${java.version}/target /configuration /plugin /plugins /build3.2 例子代码package com.panlingxiao.spring.profile.service; /** * 定义接口,在实际中可能是一个数据源 * 在开发的时候与实际部署的时候分别使用不同的实现 */ public interface HelloService { public String sayHello(); }定义生产环境使用的实现类package com.panlingxiao.spring.profile.service.produce; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.panlingxiao.spring.profile.service.HelloService; /** * 模拟在生产环境下需要使用的类 */ Component public class ProduceHelloService implements HelloService { //这个值读取生产环境下的配置注入 Value(#{config.name}) private String name; public String sayHello() { return String.format(hello,Im %s,this is a produce environment!, name); } }模拟在生产环境下需要使用的类package com.panlingxiao.spring.profile.service.dev;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;import com.panlingxiao.spring.profile.service.HelloService;/**模拟在开发环境下使用类*/Componentpublic class DevHelloService implements HelloService{//这个值是读取开发环境下的配置文件注入Value(“#{config.name}”)private String name;public String sayHello() {return String.format(“hello,I’m %s,this is a development environment!”, name);}}定义配置Spring配置文件?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:contexthttp://www.springframework.org/schema/context xmlns:utilhttp://www.springframework.org/schema/util xsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd !-- 定义开发的profile -- beans profiledevelopment !-- 只扫描开发环境下使用的类 -- context:component-scan base-packagecom.panlingxiao.spring.profile.service.dev / !-- 加载开发使用的配置文件 -- util:properties idconfig locationclasspath:dev/config.properties/ /beans !-- 定义生产使用的profile -- beans profileproduce !-- 只扫描生产环境下使用的类 -- context:component-scan base-packagecom.panlingxiao.spring.profile.service.produce / !-- 加载生产使用的配置文件 -- util:properties idconfig locationclasspath:produce/config.properties/ /beans /beans开发使用的配置文件dev/config.propertiesnameTomcat生产使用的配置文件produce/config.propertiesnameJetty编写测试类package com.panlingxiao.spring.profile.test; 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 com.panlingxiao.spring.profile.service.HelloService; RunWith(SpringJUnit4ClassRunner.class) ContextConfiguration(locationsclasspath:spring-profile.xml) /* * 使用注册来完成对profile的激活, * 传入对应的profile名字即可,可以传入produce或者dev */ ActiveProfiles(produce) public class TestActiveProfile { Autowired private HelloService hs; Test public void testProfile() throws Exception { String value hs.sayHello(); System.out.println(value); } }激活dev运行结果.png激活produce运行结果.jpg4.激活Profile的其他几种方式上面介绍了如何使用Profile以及在单元测试的环境下激活指定的Profile除了使用ActiveProfiles注解来激活profile外Spring还提供了其他的几种激活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. * pNote that certain shell environments such as Bash disallow the use of the period * character in variable names. Assuming that Springs {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;如果当spring.profiles.active属性被设置时那么Spring会优先使用该属性对应值来激活Profile。当spring.profiles.active没有被设置时那么Spring会根据spring.profiles.default属性的对应值来进行Profile进行激活。如果上面的两个属性都没有被设置那么就不会有任务Profile被激活只有定义在Profile之外的Bean才会被创建。我们发现这两个属性值其实是Spring容器中定义的属性而我们在实际的开发中很少会直接操作Spring容器本身所以如果要设置这两个属性其实是需要定义在特殊的位置让Spring容器自动去这些位置读取然后自动设置,这些位置主要为如下定义的地方作为SpringMVC中的DispatcherServlet的初始化参数作为Web 应用上下文中的初始化参数作为JNDI的入口作为环境变量作为虚拟机的系统参数使用AtivceProfile来进行激活我们在实际的使用过程中可以定义默认的profile为开发环境当实际部署的时候主需要在实际部署的环境服务器中将spring.profiles.active定义在环境变量中来让Spring自动读取当前环境下的配置信息这样就可以很好的避免不同环境而频繁修改配置文件的麻烦。4.5 示例代码下载示例代码下载地址:Spring-profile-test参考:Spring Framework Reference Documentation 4.2.5.RELEASE-- 6.13. Environment abstractionSpring Framework Reference Documentation 3.2.3.RELEASE --3.2 Bean Definition Profiles