zoukankan      html  css  js  c++  java
  • Spring详解(十)------spring 环境切换

    软件开发过程一般涉及“开发 -> 测试 -> 部署上线”多个阶段,每个阶段的环境的配置参数会有不同,如数据源,文件路径等。为避免每次切换环境时都要进行参数配置等繁琐的操作,可以通过spring的profile功能来进行配置参数的切换。

    以我用到的项目的实际情况为例,首先可以在resources文件夹下分别为每个环境建立单独的文件夹(也可以额外建立一个common文件夹,用于存放公共的参数配置文件),每个文件夹下面存放对应的环境所需的配置文件,就像这样子:

    在resources文件夹下建立applicationContext-profile.xml文件,用来定义不同的profile:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:c="http://www.springframework.org/schema/c" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
        xmlns:jee="http://www.springframework.org/schema/jee" xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/jdbc 
        http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/jee 
        http://www.springframework.org/schema/jee/spring-jee.xsd">
    
        <description>spring profile配置</description>
    
        <!-- 开发环境配置文件 -->
        <beans profile="development">
            <context:property-placeholder
                location="classpath*:common/*.properties, classpath*:development/*.properties" />
        </beans>
    
        <!-- 测试环境配置文件 -->
        <beans profile="test">
            <context:property-placeholder
                location="classpath*:common/*.properties, classpath*:test/*.properties" />
        </beans>
        
        <!-- 生产环境配置文件 -->
        <beans profile="production">
            <context:property-placeholder
                location="classpath*:common/*.properties, classpath*:production/*.properties" />
        </beans>
    
    </beans>

    这样就实现了通过profile标记不同的环境,接下来就可以通过设置spring.profiles.default和spring.profiles.active这两个属性来激活和使用对应的配置文件。default为默认,如果没有通过active来指定,那么就默认使用default定义的环境。

    这两个属性可以通过多种方法来设置:

    • 在web.xml中作为web应用的上下文参数context-param;
    • 在web.xml中作为DispatcherServlet的初始化参数;
    • 作为JNDI条目;
    • 作为环境变量;
    • 作为JVM的系统属性;
    • 在集成测试类上,使用@ActiveProfiles注解配置。

    前两者都可以在web.xml文件中设置:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    
        <display-name>Archetype Created Web Application</display-name>
    
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                classpath*:/applicationContext*.xml
            </param-value>
        </context-param>
    
        <!-- 在上下文context-param中设置profile.default的默认值 -->
        <context-param>
            <param-name>spring.profiles.default</param-name>
            <param-value>development</param-value>
        </context-param>
    
        <!-- 在上下文context-param中设置profile.active的默认值 -->
        <!-- 设置active后default失效,web启动时会加载对应的环境信息 -->
        <context-param>
            <param-name>spring.profiles.active</param-name>
            <param-value>development</param-value>
        </context-param>
    
        <servlet>
            <servlet-name>appServlet</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!-- 在DispatcherServlet参数中设置profile的默认值,active同理 -->
            <init-param>
                <param-name>spring.profiles.default</param-name>
                <param-value>development</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>appServlet</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
    </web-app>

    激活指定的环境,也可以通过JVM参数来设置,可以在tomcat的启动脚本中加入以下JVM参数来激活:

    -Dspring.profiles.active="production"

    在程序中,也可以通过 @Profile("...") 对某些资源进行注解,这样只有当选择对应的环境时,才会产生对应的bean,如:

    /**
     * 容器配置类
     * 用于测试@Profile注解
     */
    @Configuration
    @PropertySource(value = {"classpath:/dbconfig.properties"})
    public class ProfileBeanConfig implements EmbeddedValueResolverAware {
    
        //数据库连接用户名
        @Value(value = "${jdbc.username}")
        private String username;
        //数据库连接密码
        private String password;
    
        //开发环境数据源
        @Bean(value = "dataSourceDev")
        @Profile(value = "dev")
        public DataSource dataSourceDev(@Value("${jdbc.driverClass}") String driverClass) throws PropertyVetoException {
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            comboPooledDataSource.setUser(this.username);
            comboPooledDataSource.setPassword(this.password);
            comboPooledDataSource.setDriverClass(driverClass);
            comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");
            return comboPooledDataSource;
        }
    
        //测试环境数据源
        @Bean(value = "dataSourceTest")
        @Profile("test")
        public DataSource dataSourceTest(@Value("${jdbc.driverClass}") String driverClass) throws PropertyVetoException {
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            comboPooledDataSource.setUser(this.username);
            comboPooledDataSource.setPassword(this.password);
            comboPooledDataSource.setDriverClass(driverClass);
            comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");
            return comboPooledDataSource;
        }
    
        //生产环境数据源
        @Bean(value = "dataSourceProduction")
        @Profile("production")
        public DataSource dataSourceProduction(@Value("${jdbc.driverClass}") String driverClass) throws PropertyVetoException {
            ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
            comboPooledDataSource.setUser(this.username);
            comboPooledDataSource.setPassword(this.password);
            comboPooledDataSource.setDriverClass(driverClass);
            comboPooledDataSource.setJdbcUrl("jdbc:mysql://localhost:3306/production");
            return comboPooledDataSource;
        }
    
        //获取字符串解析器
        @Override
        public void setEmbeddedValueResolver(StringValueResolver resolver) {
            //解析配置文件,然后对数据库连接密码进行赋值
            this.password = resolver.resolveStringValue("jdbc.password");
        }
    }

    以下是切换数据源示例

    //创建匿名容器
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    //设置环境,其值为@Profile注解的属性值
    applicationContext.getEnvironment().setActiveProfiles("test");
    //注册容器类
    applicationContext.register(ProfileBeanConfig.class);
    //刷新容器
    applicationContext.refresh();

     

  • 相关阅读:
    Recommended Books for Algo Trading in 2020
    Market Making is simpler than you think!
    Top Crypto Market Makers of 2020
    Top Crypto Market Makers, Rated and Reviewed
    爬取伯乐在线文章(五)itemloader
    爬取伯乐在线文章(四)将爬取结果保存到MySQL
    爬取伯乐在线文章(三)爬取所有页面的文章
    爬取伯乐在线文章(二)通过xpath提取源文件中需要的内容
    爬取伯乐在线文章(一)
    爬虫去重策略
  • 原文地址:https://www.cnblogs.com/deityjian/p/11067430.html
Copyright © 2011-2022 走看看