背景:实际开发中,项目往往以多环境配置运行、开发环境(dev)、测试环境(test)、生产环境(prod)。虽然每个环境都运行这同一代码,但是每个环境却都有各自的数据源。如何在打包部署时,做到各自环境打包各自的数据源呢?
在此之前项目都是手工切换环境,这样很麻烦也很容易出错。在手工切换老项目中,代码存在着加载配置写死的情况。也就是说,有的地方需要用到测试环境的就直接将测试环境的配置写死在代码里,有的地方是本地环境就将本地的环境配置写死在代码里。所以这个时候就需要编写一个工具类来动态获取当前运行的是哪个环境,以此来取代写死的代码。下面先来看SpringMVC多环境的配置吧!
第一步,在resources目录下分别创建不同的目录
在resources目录下分别创建不同的目录,开发环境(config_dev)目录、生产环境(config_prod)目录等。每个环境共用的配置文件可以抽取出来一个共用(config_common)目录。
第二步,springmvc.xml中配置每个环境的beans
配置每个环境的beans,主要是用来加载、实例化每个环境的配置文件和共用的配置的文件。
<!-- 测试环境配置文件 -->
<beans profile="dev">
<context:property-placeholder
location="classpath*:config_common/*.properties, classpath*:config_dev/*.properties"/>
</beans>
<!-- 生产环境配置文件 -->
<beans profile="prod">
<context:property-placeholder
location="classpath*:config_common/*.properties, classpath*:config_prod/*.properties"/>
</beans>
第三步,配置web.xml
web.xml主要配置springmvc.xml的加载路径,以及每个环境的切换配置。如此当需要切换环境的时候只需改动 spring.profiles.active的dev即可,因为第二步中已经实例化了每个环境的标识
<beans profile=“prod”、“dev”>
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 多环境配置 在上下文context-param中设置profile.default的默认值 -->
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>prod</param-value>
</context-param>
<!-- 多环境配置 在上下文context-param中设置profile.active的默认值 -->
<!-- 设置active后default失效,web启动时会加载对应的环境信息 -->
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>dev</param-value>
</context-param>
如此按照以上步骤即可实现SpringMVC的多化解配置。
动态获取当前环境。
通过spring.profiles来动态获取当前的环境。实现ApplicationContextAware接口,重写setApplicationContext方法,自定义一个获取当前环境标识的方法是dev还是prod…我写的方法是getEnvProfile()。工具类写好后还得配置springMVC.xml实例化这个工具类。
public class SpringContextHelperUtil implements ApplicationContextAware {
private static ApplicationContext context = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static String getEnvProfile(){
Environment env = context.getEnvironment();
String[] profile=env.getActiveProfiles();
String s=null;
for (int i=0; i<profile.length;i++){
s = profile[0];
}
return s;
}
}
配置springmvc.xml,实例化这个工具类,项目启动时就扫描这个工具类
class是工具类的路径。
<bean id="springContextHelper" class="com.util.SpringContextHelperUtil"></bean>
<context:component-scan base-package="com.util" ></context:component-scan>
如此在写死环境配置的代码里使用动态环境配置的工具类替换就好了。