Spring3.1 新特性 -- 为不同的环境配置不同的 profile

2016-11-11 12:09:15   最后更新: 2016-11-11 12:09:15   访问数量:552




此前的日志中,我们介绍了如何通过 maven 配置实现为不同的环境打不同的 war 包,来实现不同环境使用不同资源、配置的功能

通过 maven filtering 机制实现打包不同的资源配置目录

这是生产环境中非常实用的一个功能,Spring3.1 也提供了类似功能,他通过为 bean 指定 profile 来让 Spring 在不同的环境选择是否创建和加载相应的 bean,这样的好处是同一个 war 包可以被应用于所有的环境,而不需要重新构建

 

在 java 配置中,可以使用 @Profile 注解指定某个 bean 属于哪个 profile

@Configuration @Profile("dev") public class DevelopmentProfileConfig { ... }

 

这样,这个 DevelopmentProfileConfig 配置类中的所有 Bean 都将只有在应用 dev profile 时才会被创建,否则他们都将被忽略

 

@Profile 注解也可以直接应用于 Bean,实现 Bean 的装配

@Configuration public class DataSourceConfig { @Bean(destroyMethod = "shutdown") @Profile("dev") public DataSource devDataSource() { ... } @Bean @Profile("prod") public DataSource prodDataSource() { ... } }

 

虽然这两个 Bean 都被声明在了一个 java Configuration 类中,并且都只在这个类被加载时才会被创建,但两个 Bean 只有在指定相应 profile 时才会被创建,另一个则会被忽略

 

我们也可以通过 xml 配置文件中的 <beans> 元素的 profile 属性指定 xml 中所有 bean 适用的 profile

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd" profile="dev"> <context:component-scan base-package="com.techlog.web.order.groupapi.queryproxy"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 导入属性配置文件 --> <bean id="configurationProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="locations"> <list> <value>classpath*:config.properties</value> </list> </property> </bean> <context:annotation-config/> <aop:aspectj-autoproxy/> <import resource="classpath:include.xml"/> <import resource="classpath:service/thrift-service.xml"/> </beans>

 

需要注意的是必须要将 namespace 中的springframework 配置到 3.1 以上

 

当然,可以通过在 <beans> 中嵌套 <beans> 元素来让同一个配置文件中的不同 bean 处在不同的 profile 下

 

Spring 在确定哪个 profile 处于激活状态时,需要依赖两个独立的属性:

  1. spring.profiles.active
  2. spring.profiles.default

 

如果 spring.profiles.active 属性已经被设置,那么他的值就会用来确定哪个 profile 是激活的,否则 Spring 会查找 spring.profiles.default 的值来激活 profile

如果这两个属性都没有被设置,那么所有按照上文描述的设置过 profile 的 Bean 都将不会被创建

 

有多种方式可以用来设置这两个属性:

  1. 作为 DispatcherServlet 的初始化参数
  2. 作为 web 应用上下文参数
  3. 作为 JNDI 条目
  4. 作为环境变量
  5. 作为 JVM 系统属性
  6. 在集成测试类上使用 @ActiveProfiles 注解设置

 

推荐的方式是在 web.xml 中为你使用的 Servlet 设置 spring.profiles.default 属性,在具体的环境中,使用其他方式指定 spring.profiles.active 值来覆盖这一属性

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>Spring MVC Application</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:ApplicationContext.xml </param-value> </context-param> <context-param> <param-name>spring.profiles.default</param-name> <param-value>dev</param-value> </context-param> </web-app>

 

 

你也可以为每个 Servlet 指定默认的 profile:

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>Spring MVC Application</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:ApplicationContext.xml </param-value> </context-param> <context-param> <param-name>spring.profiles.default</param-name> <param-value>dev</param-value> </context-param> <servlet> <servlet-name>testprofile</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>spring.profiles.default</param-name> <param-value>prod</param-value> </init-param> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:testprofile-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>testprofile</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>

 

 

在测试或其他环境中,指定 spring.profiles.active 以后,spring.profiles.default 值无论是什么都不重要了,因为系统会优先使用 spring.profiles.active 属性的值

你也可以通过逗号分隔配置多个 profile 同时激活多个配置

 

在实际的各个环境中,我们需要激活不同的 profile,除了上述在 web.xml 配置的方法外,还有大量灵活的方法可供使用,下面就介绍两个方法

 

ENV 方式

通过 ConfigurableEnvironment.setActiveProfiles("test") 可以通过设置环境变量的方式指定这一属性值

 

JVM参数方式

在 jvm 参数中,可以通过添加 JAVA_OPS 的方式指定这一属性值:

JAVA_OPTS="-Dspring.profiles.active=test"

 

 

《Spring in Action (Edion 4th)》

spring profile 多环境配置管理 -- http://www.cnblogs.com/pangguoming/p/5888871.html

 






技术帖      web      xml      龙潭书斋      environment      环境变量      java      spring      profile     


京ICP备15018585号