Spring实战之JavaConfig方式多环境与profile配置
admin
2024-02-29 18:33:03

Spring实战之JavaConfig方式多环境与profile配置

  • 什么是多环境
  • 配置profile bean-@Profile注解在类级别上
    • 开发环境配置
    • 生产环境配置
  • 配置profile bean-@Profile注解在方法级别上
  • 如何激活profile

什么是多环境

以数据源为例,在不同环境下,我们会需要代码提供不同的数据源bean。如:

  • 开发环境:我们需要嵌入式数据库
  • 生产环境:我们需要使用JNDI从容器中获取一个Datasource
  • QA环境:我们需要配置DBCP连接池获取DataSource

如果我们通过修改代码的方式每次部署不同环境时就改一次对应的代码,你是不是会疯掉呢?(会!)
那怎么做能根据不同的环境来让我们的代码自动提供相应的数据源对象呢?

配置profile bean-@Profile注解在类级别上

通过Spring为环境相关的bean所提供的解决方案,是根据环境来决定该创建那个bean和不该创建那个bean。要注意的是,Spring并不是在构建的时候做出这样的决策,而是等到运行时再来确定

Spring引入了bean profile的功能。要使用profile,首先要将所有不同的bean定义到一个或多个profile之中,在将应用部署到每个环境时,还要确保对应的profile处于激活(active)的状态。

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

开发环境配置

例如,在配置类中,嵌入式数据库的DataSource可能会配置成如下所示:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;import javax.sql.DataSource;@Configuration
@Profile("dev")
public class DevelopmentProfileConfig {@Beanpublic DataSource dataSource() {return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).addScript("classpath:schema.sql").addScript("classpath:test-data.sql").build();}
}

类上添加了@Profile注解,它会告诉Spring这个配置类中 的bean只有在dev profile激活时才会创建。如果dev profile 没有激活,那么该类中带有@Bean注解的方法都会被忽略。

生产环境配置

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jndi.JndiObjectFactoryBean;import javax.sql.DataSource;@Configuration
@Profile("prod")
public class ProductionProfileConfig {@Beanpublic DataSource dataSource() {JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();jndiObjectFactoryBean.setJndiName("jdbc/myDS");jndiObjectFactoryBean.setResourceRef(true);jndiObjectFactoryBean.setProxyInterface(DataSource.class);return (DataSource) jndiObjectFactoryBean.getObject();}
}

类上添加了@Profile注解,它会告诉Spring这个配置类中 的bean只有在prod profile激活时才会创建。

配置profile bean-@Profile注解在方法级别上

上面说了@Profile注解在类级别上,现在我们看看将@Profile注解在方法级别上,可以将多个bean的声明放到同一个配置类之中,更方便的进行代码阅读。如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.jndi.JndiObjectFactoryBean;import javax.sql.DataSource;@Configuration
@Profile("prod")
public class DataSourceConfig {/*** 为dev profile装配的bean*/@Bean@Profile("dev")public DataSource embeddedDataSource() {return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).addScript("classpath:schema.sql").addScript("classpath:test-data.sql").build();}/*** 为prod profile装配的bean*/@Bean@Profile("prod")public DataSource jndiDataSource() {JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();jndiObjectFactoryBean.setJndiName("jdbc/myDS");jndiObjectFactoryBean.setResourceRef(true);jndiObjectFactoryBean.setProxyInterface(DataSource.class);return (DataSource) jndiObjectFactoryBean.getObject();}
}

但是需要注意一点,尽管如上每个Datasource bean都被声明在一个配置类中,并且只有当规定的profile激活时,相应的bean才会被创建,但是在代码不断迭代开发的过程中,可能会有其他的bean并没有被开发人员声明在一个给定的profile范围内。对于没有指定profile的bean,它始终都会被创建,此类bean就与激活哪个profile没有关系了!

如何激活profile

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

  • 如果设置了spring.profiles.active属性的话,那它的值就用来确定激活哪个profile;
  • 如果没有设置spring.profiles.active,Spring将会查找spring.profiles.default的值来激活profile;
  • 如果都没有设置,那就意味着没有激活的profile,因此上述代码中的Datasource bean都不会创建,只会创建没有定义在profile中的bean!

有多种方式来设置这2个属性:

  • 作为DispatcherServlet的初始化参数
  • 作为Web应用的上下文参数
  • 作为JNDI条目
  • 作为环境变量
  • 作为JVM的系统属性
  • 在集成测试类上,使用@ActiveProfiles注解设置
  • 等等。。

相关内容

热门资讯

复刻贵州馆子味!家常泡椒炒牛肉... 贵州泡椒炒牛肉是一道充满地方特色的家常菜,它以鲜嫩的牛肉和酸辣开胃的泡椒为主要食材,成菜香气扑鼻,口...
黔寨风味“黄金派”:外酥内糯,... 在贵州连绵的群山与缭绕的云雾间,散落着许多古老村寨。这里不仅保留着深厚的民族传统,更隐藏着无数令人惊...
大妈教你东北芥菜疙瘩的腌制方法... 眼下正是腌菜的好时节,每年这个时候,我总会想起东北大娘腌的芥菜疙瘩,那味道堪称一绝。她的做法特别简单...
原创 一... 家人们谁懂啊!黑椒牛肉配杏鲍菇真的是神仙组合!软嫩多汁的牛肉裹着浓郁的黑椒酱汁,杏鲍菇吸饱了肉香变得...