# 5.3.3 有条件地使用 profile 文件创建 bean

有时候，为不同的配置文件提供一组惟一的 bean 是很有用的。通常，不管哪个 profile 文件是活动的，Java 配置类中声明的任何 bean 都会被创建。但是，假设只有在某个配置文件处于活动状态时才需要创建一些 bean，在这种情况下，@Profile 注解可以将 bean 指定为只适用于给定的 profile 文件。

例如，在 TacoCloudApplication 中声明了一个 CommandLineRunner bean，用于在应用程序启动时加载嵌入式数据库中的成分数据。这对于开发来说很好，但是在生产应用程序中是不必要的（也是不受欢迎的）。为了防止在每次应用程序在生产部署中启动时加载成分数据，可以使用 @Profile 像下面这样注解 CommandLineRunner bean 方法：

```java
@Bean
@Profile("dev")
public CommandLineRunner dataLoader(IngredientRepository repo,
     UserRepository userRepo, PasswordEncoder encoder) {
    ...
}
```

或是假设需要在 dev profile 或是 qa profile 被激活时创建 CommandLineRunner，在这种情况下，可以列出需要的 profile：

```java
@Bean
@Profile({"dev", "qa"})
public CommandLineRunner dataLoader(IngredientRepository repo,
     UserRepository userRepo, PasswordEncoder encoder) {
    ...
}
```

这样成分数据只会在 dev 或是 qa profile 文件被激活时才会被加载。这就意味着需要在开发环境运行应用程序时，将 dev profile 激活。如果这个 CommandLineRunner bean 总是被创建，除非 prod 配置文件是活动的，那就更方便了。在这种情况下，你可以像这样应用 @Profile：

```java
@Bean
@Profile("!prod")
public CommandLineRunner dataLoader(IngredientRepository repo, 
      UserRepository userRepo, PasswordEncoder encoder) {
    ...
}
```

在这里，感叹号 `!`否定了配置文件名称。实际上，它声明如果 prod 配置文件不是活动的，就会创建 CommandLineRunner bean。

也可以在整个 @Configuration 注解的类上使用 @Profile。例如，假设要将 CommandLineRunner bean 提取到一个名为 DevelopmentConfig 的单独配置类中。然后你可以用 @Profile 来注解 DevelopmentConfig：

```java
@Profile({"!prod", "!qa"})
@Configuration
public class DevelopmentConfig {
    
    @Bean
    public CommandLineRunner dataLoader(IngredientRepository repo,
          UserRepository userRepo, PasswordEncoder encoder) {
        ...
    }
}
```

在这里，CommandLineRunner bean（以及在 DevelopmentConfig 中定义的任何其他 bean）仅在 prod 和 qa 配置文件都不活动的情况下才会被创建。
