静下心来的个人专栏
上一篇

Spring中的配置文件有条件地注册bean

广告
选中文字可对指定文章内容进行评论啦,→和←可快速切换按钮,绿色背景文字可以点击查看评论额。
大纲

Spring中的配置文件有条件地注册bean

在 Spring Framework 中,配置文件是 bean 定义的逻辑组,仅当给定配置文件处于活动状态时才会注册。可以为一个 bean 分配多个配置文件,用逻辑操作分隔,例如 not (!), and (&) and or (|) 等。Spring 中的配置文件是使用 Spring 中的 @Profile 注释指定的。

可以通过多种方式使用和激活 @Profile 注释,我们将详细探讨它们中的每一种。

您只需要 Spring-core 和 Spring-context 依赖项即可使此示例正常工作。

<dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
    </dependency>
  </dependencies>

您可以选择指定测试依赖项

<dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.platform</groupId>
      <artifactId>junit-platform-runner</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <scope>test</scope>
    </dependency>

 

何时使用 Spring @Profile 注解

在学习使用之前,让我们了解您为什么需要注解。

1、假设您可能希望根据环境加载不同的配置集。例如在用于测试的内存数据源中,用于生产的 MySql。因此,您可以根据配置文件值加载不同的 dataSource bean。

2、另一个常见的例子是根据环境加载不同的 application.properties 文件。例如application-dev.properties 用于开发,application-test.properties 用于测试等。

有几种方法可以使用@Profile 注释,也有几种方法可以激活特定的配置文件。

1、在类级别使用带有原型的@Profile

当您有两个数据源 RestDataSource 和 GraphQlDataSource 时,请考虑一个用例。您只想根据配置文件值激活其中之一。

您可以在下面的代码中看到,GraphQlDataSource 具有配置文件 graphQl。但是 RestDataSource 有 2 个配置文件值 rest 和 default。当应用程序中未设置配置文件值时,将激活默认配置文件。

GraphQlDataSource.java

@Component
@Profile("graphQl")
public class GraphQlDataSource implements DataSource {
  @Override
  public String getName() {
    return "GraphQlDataSource";
  }
}

RestDataSource.java

@Component
@Profile({"rest", "default"}) //multiple profiles
public class RestDataSource implements DataSource {
  //Logic to fetch data from API
  @Override
  public String getName() {
    return "RestDataSource";
  }
}

ProfilesConfig.java

@Configuration
@ComponentScan("com.jsbd.profiles")
public class ProfilesConfig {
}

DataSource.java

public interface DataSource {
  public String getName();
}

我们可以通过不同的方式设置配置文件值来测试上述代码。

a、在 spring-test 中使用 @ActiveProfiles 设置配置文件

我们可以使用 JUnit 测试类中的 @ActiveProfiles 注解来设置特定的配置文件。请记住,这仅在测试类中可用。下面的示例演示如何激活特定配置文件。当您不提及任何默认配置文件时,将被激活。

TestRestProfile.java

@SpringJUnitConfig(ProfilesConfig.class)
@ActiveProfiles("rest")
public class TestRestProfile {
  @Autowired
  private DataSource dataSource;
  @Test
  public void testDataSource(){
    Assert.assertNotNull(dataSource);
    Assert.assertEquals(dataSource.getClass(), RestDataSource.class);
    System.out.println(dataSource.getClass());
  }
}

TestGraphQlProfile.java

@SpringJUnitConfig(ProfilesConfig.class)
@ActiveProfiles("graphQl")
public class TestGraphQlProfile {
  @Autowired
  private DataSource dataSource;
  @Test
  public void testGraphQlProfile() {
    System.out.println(dataSource);
    Assert.assertNotNull(dataSource);
    Assert.assertEquals(dataSource.getClass(), GraphQlDataSource.class);
  }
}

TestDefaultProfile.java

@SpringJUnitConfig(ProfilesConfig.class)
public class TestDefaultProfile {
  @Autowired
  private DataSource dataSource;
  @Test
  public void testDefaultProfile() {
    Assert.assertNotNull(dataSource);
    Assert.assertEquals(dataSource.getClass(), RestDataSource.class);
  }
}

b、使用 JVM 参数激活配置文件

您还可以使用 JVM 参数 spring.profiles.active 在应用程序中激活特定配置文件,如下所示。

$ java -jar -Dspring.profiles.active=graphQl target/spring-profile-app-1.0.jar

c、以编程方式设置配置文件值

您可以通过编程方式使用 Environment API 设置特定配置文件。您可以 @Autowire 环境接口或从 ApplicationContext 获取它。

public class ProfilesApp {
  public static void main(String[] args) {
    AnnotationConfigApplicationContext context
        = new AnnotationConfigApplicationContext();
    context.getEnvironment().setActiveProfiles("graphQl");
    context.register(ProfilesConfig.class);
    context.refresh();
    DataSource  dataSource = context.getBean(DataSource.class);
    System.out.println(dataSource.getClass());
  }
}

或者,您可以通过 ConfigurableEnvironment 属性注入配置文件值,如下所示。

@Autowired
private ConfigurableEnvironment env;
...
env.setActiveProfiles("rest");

 

2、将@Profile 与@Configuration 一起使用

就像您如何将@Profile 与@Component、@Repository 或@Service 一起使用一样,也可以为配置指定配置文件。下面的示例显示了使用带有 @Configuration 注释的配置文件。

ProdConnectionPool.java

@Configuration
@Profile("production")
public class ProdConnnectionPoolConfig {
  @Bean
  public ConnectionPoolDataSource prodConnectionPool() {
    //prod database connection pool
  }
}

DevConnectionPool.java

@Configuration
@Profile("development")
public class DevConnnectionPoolConfig {
  @Bean
  public ConnectionPoolDataSource devConnectionPool() {
    //dev database connection pool
  }
}

3、将@Profile 与@Bean 注解一起使用

@Profile 注释还与@Bean 一起使用,以根据配置文件值动态激活特定 bean。您可以在下面的示例中看到,根据配置文件设置了特定的 ConnectionPoolDataSource。

@Configuration
public class ConnnectionPoolConfig {
  @Bean
  @Profile("production")
  public ConnectionPoolDataSource prodConnectionPool() {
    //prod database connection pool
  }
  @Bean
  @Profile("development")
  public ConnectionPoolDataSource devConnectionPool() {
    //dev database connection pool
  }
}

 

版权声明:著作权归作者所有。

X

欢迎加群学习交流

联系我们