Spring入門(七):Spring Profile使用講解

  1. 使用場景
  
  在平常的開發工做中,咱們常常須要將程序部署到不一樣的環境,好比Dev開發環境,QA測試環境,Prod生產環境,這些環境下的一些配置確定是不同的,好比數據庫配置,Redis配置,RabbitMQ配置。
  
  若是每次切換髮布環境,都須要修改配置從新構建的話,那對程序員來講將是噩夢,針對這種場景,Spring提供了@Profile註解來實現按照不一樣的環境裝配不一樣的bean,進而實現程序只需構建一次,但能夠部署到多個環境。
  
  2. 配置profile bean
  
  爲了更好的理解,咱們經過具體的代碼示例來理解下Spring profile的使用方法,這裏咱們以數據庫配置爲例。
  
  說明:本篇博客的重點是講解@Profile註解的使用,數據庫的操做只是輔助理解@Profile,所以不會講解的太詳細,不事後續會單獨寫博客講解
  
  假設咱們有3套環境(Dev,QA,Prod),這3套環境的數據庫都使用的是mysql,可是其地址,用戶名,密碼都不同,那麼在Java配置中,該如何聲明這些bean呢?
  
  2.1 Java配置中配置profile bean
  
  首先須要瞭解的是,@Profile註解是從Spring 3.1版本中開始引入的,而且在這個版本中,@Profile註解只能在類級別上使用。
  
  所以咱們能夠按照環境分別建立數據庫配置,以下所示:
  
  Dev環境下的數據庫配置:
  
  package chapter03.profile;
  
  import org.apache.commons.dbcp2.BasicDataSource;
  
  import org.springframework.context.annotation.Bean;
  
  import org.springframework.context.annotation.Configuration;
  
  import org.springframework.context.annotation.Profile;
  
  import javax.sql.DataSource;
  
  @Configuration
  
  @Profile("dev")
  
  public class DevDataSourceConfig {
  
  @Bean
  
  public DataSource devDataSource() {
  
  System.out.println("This is dev DataSource");
  
  BasicDataSource basicDataSource = new BasicDataSource();
  
  basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
  
  basicDataSource.setUrl("jdbc:mysql://localhost:3306/mybatis_action_db");
  
  basicDataSource.setUsername("dev");
  
  basicDataSource.setPassword("dev");
  
  return basicDataSource;
  
  }
  
  }
  
  使用上述代碼須要在pom.xml中添加以下依賴:
  
  <dependency>
  
  <groupId>org.apache.commons</groupId>
  
  <artifactId>commons-dbcp2</artifactId>
  
  <version>2.7.0</version>
  
  </dependency>
  
  注意事項:若是類級別上使用了@Profile("dev"),那麼該類中的全部bean都會在profile爲dev時建立。
  
  QA環境下的數據庫配置:
  
  package chapter03.profile;
  
  import org.apache.commons.dbcp2.BasicDataSource;
  
  import org.springframework.context.annotation.Bean;
  
  import org.springframework.context.annotation.Configuration;
  
  import org.springframework.context.annotation.Profile;
  
  import javax.sql.DataSource;
  
  @Configuration
  
  @Profile("qa")
  
  public class QADataSourceConfig {
  
  @Bean
  
  public DataSource qaDataSource() {
  
  System.out.println("This is qa DataSource");
  
  BasicDataSource basicDataSource = new BasicDataSource();
  
  basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
  
  basicDataSource.setUrl("jdbc:mysql://localhost:3307/mybatis_action_db");
  
  basicDataSource.setUsername("qa");
  
  basicDataSource.setPassword("qa");
  
  return basicDataSource;
  
  }
  
  }
  
  Prod環境下的數據庫配置:
  
  package chapter03.profile;
  
  import org.apache.commons.dbcp2.BasicDataSource;
  
  import org.springframework.context.annotation.Bean;
  
  import org.springframework.context.annotation.Configuration;
  
  import org.springframework.context.annotation.Profile;
  
  import javax.sql.DataSource;
  
  @Configuration
  
  @Profile("prod")
  
  public class ProdDataSourceConfig {
  
  @Bean
  
  public DataSource prodDataSource() {
  
  System.out.println("This is prod DataSource");
  
  BasicDataSource basicDataSource = new BasicDataSource();
  
  basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
  
  basicDataSource.setUrl("jdbc:mysql://localhost:3308/mybatis_action_db");
  
  basicDataSource.setUsername("prod");
  
  basicDataSource.setPassword("prod");
  
  return basicDataSource;
  
  }
  
  }
  
  不過從Spring 3.2開始,@Profile註解能夠與@Bean註解一塊兒在方法級別上使用。
  
  這也就使得咱們能夠將剛剛的3個配置類合併成1個配置類(推薦該方式),以下所示:
  
  package chapter03.profile;
  
  import org.apache.commons.dbcp2.BasicDataSource;
  
  import org.springframework.context.annotation.Bean;
  
  import org.springframework.context.annotation.Configuration;
  
  import org.springframework.context.annotation.Profile;
  
  import javax.sql.DataSource;
  
  @Configuration
  
  public class DataSourceConfig {
  
  @Bean
  
  @Profile("dev")
  
  public DataSource devDataSource() {
  
  System.out.println("This is dev DataSource");
  
  BasicDataSource basicDataSource = new BasicDataSource();
  
  basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
  
  basicDataSource.setUrl("jdbc:mysql://www.csyldl.com  localhost:3306/mybatis_action_db");
  
  basicDataSource.setUsername("dev");
  
  basicDataSource.setPassword("dev");
  
  return basicDataSource;
  
  }
  
  @Bean
  
  @Profile("qa")
  
  public DataSource qaDataSource() {
  
  System.out.println("This is qa DataSource");
  
  BasicDataSource basicDataSource = new BasicDataSource();
  
  basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
  
  basicDataSource.setUrl("jdbc:mysql://localhost:3307/mybatis_action_db");
  
  basicDataSource.setUsername(www.baiyiyulgw.com"qa");
  
  basicDataSource.setPassword("qa");
  
  return basicDataSource;
  
  }
  
  @Bean
  
  @Profile("prod")
  
  public DataSource prodDataSource() {
  
  System.out.println("This is prod DataSource");
  
  BasicDataSource basicDataSource = new BasicDataSource();
  
  basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
  
  basicDataSource.setUrl("jdbc:mysql://localhost:3308/mybatis_action_db");
  
  basicDataSource.setUsername("prod"www.yuchengyulegw.com);
  
  basicDataSource.setPassword("prod");
  
  return basicDataSource;
  
  }
  
  }
  
  注意事項:沒有指定profile的bean始終都會建立,與激活哪一個profile無關。
  
  2.2 xml中配置profile bean
  
  咱們也能夠經過<beans>元素的profile屬性,在xml中配置profile bean,以下所示:
  
  <?xml version="1.0" encoding="UTF-8"?>
  
  <beans xmlns="http://www.fengshen157.com /schema/beans"
  
  xmlns:xsi="http://www.jintianxuesha.com /2001/XMLSchema-instance"
  
  xmlns:p="http://www.fengshen157.com /schema/p"
  
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
  
  profile="dev">
  
  <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
  
  p:driverClassName="com.mysql.jdbc.Driver"
  
  p:url="jdbc:mysql://localhost:3306/mybatis_action_db"
  
  p:username="dev"
  
  p:password="dev"/>
  
  </beans>
  
  能夠參考該配置,分別建立qa和prod環境的profile xml文件。
  
  不過仍是推薦使用嵌套的<beans>元素,在一個xml文件中配置好3個環境的數據源,代碼以下所示:
  
  <?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:p="http://www.springframework.org/schema/p"
  
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  
  <beans profile="dev">
  
  <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
  
  p:driverClassName="com.mysql.jdbc.Driver"
  
  p:url="jdbc:mysql://localhost:3306/mybatis_action_db"
  
  p:username="dev"
  
  p:password="dev"/>
  
  </beans>
  
  <beans profile="qa">
  
  <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
  
  p:driverClassName="com.mysql.jdbc.Driver"
  
  p:url="jdbc:mysql://localhost:3307/mybatis_action_db"
  
  p:username="qa"
  
  p:password="qa"/>
  
  </beans>
  
  <beans profile="prod">
  
  <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
  
  p:driverClassName="com.mysql.jdbc.Driver"
  
  p:url="jdbc:mysql://localhost:3308/mybatis_action_db"
  
  p:username="prod"
  
  p:password="prod"/>
  
  </beans>
  
  </beans>
  
  3. 激活profile
  
  截止目前,咱們按照環境的維度建立了3個bean,但實際運行時,只會建立1個bean,具體建立哪一個bean取決於處於激活狀態的是哪一個profile。
  
  那麼,咱們該如何激活某個profile呢?
  
  Spring在肯定激活哪一個profile時,須要依賴2個屬性:
  
  spring.profiles.active
  
  spring.profiles.default
  
  spring.profiles.active的優先級比spring.profiles.default高,即若是沒有配置spring.profiles.active,就使用spring.profiles.default配置的值,若是配置了spring.profiles.active,就不會再使用spring.profiles.default配置的值。
  
  若是二者都沒有配置,就只會建立那些沒有定義profile的bean。
  
  Web應用中,在web.xml中設置spring.profiles.active的代碼以下所示:
  
  <context-param>
  
  <param-name>spring.profiles.active</param-name>
  
  <param-value>dev</param-value>
  
  </context-param>
  
  也可使用代碼方式激活:
  
  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
  
  context.getEnvironment().setActiveProfiles("dev");
  
  4. 單元測試
  
  新建Main類,在其main()方法中添加以下測試代碼:
  
  package chapter03.profile;
  
  import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  
  public class Main {
  
  public static void main(String[] args) {
  
  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
  
  context.getEnvironment().setActiveProfiles("dev");
  
  context.register(DataSourceConfig.class);
  
  context.refresh();
  
  context.close();
  
  }
  
  }
  
  輸出結果以下所示:
  
  This is dev DataSource
  
  若是將代碼修改成context.getEnvironment().setActiveProfiles("qa");,輸出結果爲:
  
  This is qa DataSource
  
  若是將代碼修改成context.getEnvironment().setActiveProfiles("prod");,輸出結果爲:
  
  This is prod DataSourcejava

相關文章
相關標籤/搜索