官术网_书友最值得收藏!

  • Spring Essentials
  • Shameer Kunjumohamed Hamidreza Sattari
  • 374字
  • 2021-07-16 13:05:48

Working with bean definition profiles

For commercial projects, it is a common requirement to be able to maintain two or more environment-specific configurations and beans, activated selectively only in the corresponding environment. For example, objects such as data sources, e-mail servers, and security settings could be different for development, testing, and production environments. You would want to switch them declaratively without touching the application code, keeping it externally. Developers traditionally write complex scripts and property files with separate builds to do this job. Spring comes to your rescue here with environment abstraction using bean definition profiles and properties.

Bean definition profiles are a mechanism by which application context is configured differently for different environments. You group bean definitions under named profiles in XML or using annotation and activate one or more profiles in each environment. You can set a default profile to be enabled if you do not specify one explicitly.

Let's take a look the following sample listing that configures data sources for development and production environments:

@Configuration
@ComponentScan(basePackages = "com.springessentialsbook")
public class ProfileConfigurator {

   @Bean
   @Profile("dev")
   public DataSource devDataSource() {
      return new EmbeddedDatabaseBuilder()
         .setType(EmbeddedDatabaseType.HSQL) .addScript("scripts/tasks-system-schema.sql") .addScript("scripts/tasks-master-data.sql") .build();
   }
   @Bean
   @Profile("prod")
   public DataSource productionDataSource() throws Exception {
      Context ctx = new InitialContext();
      return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource/tasks");
   }
}

Practically, for production environments, externalizing this profile config in XML would be a better idea, where you allow your DevOps team to modify it for different environments and forbid them to touch your Java code. XML configuration would look like the following listing:

<?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:jdbc="http://www.springframework.org/schema/jdbc"
  xmlns:jee="http://www.springframework.org/schema/jee"
  xsi:schemaLocation="...">
  <!-- other bean definitions -->
  <beans profile="dev">
    <jdbc:embedded-database id="dataSource">
      <jdbc:script location="classpath:scripts/tasks-system-schema.sql"/>
      <jdbc:script location="classpath:scripts/tasks-master-data.sql"/>
    </jdbc:embedded-database>
  </beans>

  <beans profile="production">
    <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/>
  </beans>
</beans>

You may create as many profiles as required; it is common for each developer to maintain their own configurations, with profiles named after themselves, say @Profile("mary"). You can have multiple profiles active at the same time too; it depends on how well you organize them without having conflicts or duplicate bean definitions across profiles.

Now you can activate one or more profiles as you need in each (dev, test, or prod) environment using any one of the following methods:

  1. Programmatically invoking ctx.getEnvironment().setActiveProfiles("p1", "p2", ..).
  2. Setting the property spring.profile.active—with comma-separated profile names as value—as an environment variable, JVM system property, or Servlet context param in web.xml.
  3. Add -Dspring.profile.active="p1,p2, .." as a command-line or Java argument while starting up your application.
主站蜘蛛池模板: 仙桃市| 肥乡县| 清流县| 山西省| 呼图壁县| 喜德县| 巴里| 会泽县| 聂拉木县| 胶南市| 德钦县| 右玉县| 扶余县| 罗甸县| 浦北县| 奇台县| 五指山市| 贞丰县| 大港区| 沅陵县| 望奎县| 昭觉县| 白山市| 阿拉善左旗| 镇安县| 伊金霍洛旗| 洪湖市| 汾西县| 佛学| 休宁县| 沧州市| 湖南省| 蓬莱市| 凉城县| 浮山县| 乌鲁木齐市| 安福县| 家居| 循化| 晋中市| 台前县|