java 如果我在配置类上使用 @ActiveProfiles 批注而不是在定义我的 bean 的类上使用它,那么在 Spring 中会发生什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27216388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 11:25:17  来源:igfitidea点击:

What happens in Spring if I use the @ActiveProfiles annotation on a configuration class instead use it on the class that defines my beans?

javaspringannotationsspring-annotationsspring-profiles

提问by AndreaNobili

I am studying for the Spring Corecertification and I have some doubts related to the use of profilesinto JUnit tests.

我学习的弹簧芯的认证,我必须与使用的一些疑问JUnit测试

So I know that if I annote a class in the following way:

所以我知道,如果我以下列方式注释一个类:

@Profile("stub")
@Repository
public class StubAccountRepository implements AccountRepository {

    private Logger logger = Logger.getLogger(StubAccountRepository.class);

    private Map<String, Account> accountsByCreditCard = new HashMap<String, Account>();

    /**
     * Creates a single test account with two beneficiaries. Also logs creation
     * so we know which repository we are using.
     */
    public StubAccountRepository() {
        logger.info("Creating " + getClass().getSimpleName());
        Account account = new Account("123456789", "Keith and Keri Donald");
        account.addBeneficiary("Annabelle", Percentage.valueOf("50%"));
        account.addBeneficiary("Corgan", Percentage.valueOf("50%"));
        accountsByCreditCard.put("1234123412341234", account);
    }

    public Account findByCreditCard(String creditCardNumber) {
        Account account = accountsByCreditCard.get(creditCardNumber);
        if (account == null) {
            throw new EmptyResultDataAccessException(1);
        }
        return account;
    }

    public void updateBeneficiaries(Account account) {
        // nothing to do, everything is in memory
    }
}

I am declaring a service beanthat belongs to the stubprofile.

我声明了一个属于存根配置文件的服务 bean

So, if my test classis something like this:

所以,如果我的测试类是这样的:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=TestInfrastructureConfig.class)
@ActiveProfiles("stub")
public class RewardNetworkTests {
    .....................................
    .....................................
    .....................................
}

it means that it will be used the beans bean that belong to the stubprofile and the bean that not have a profile. Is it right or am I missing something?

这意味着它将使用属于存根配置文件的 bean bean 和不具有配置文件的 bean。是对的还是我错过了什么?

What happens if instead use the @ActiveProfilesannotation on a class (whose instance will be a Spring bean) I use it on a Java Configuration Class?

如果在类(其实例将是 Spring bean)上使用@ActiveProfiles注释我在Java 配置类上使用它会发生什么?

Something like it:

类似的东西:

@Configuration
@Profile("jdbc-dev")
public class TestInfrastructureDevConfig {

    /**
     * Creates an in-memory "rewards" database populated 
     * with test data for fast testing
     */
    @Bean
    public DataSource dataSource(){
        return
            (new EmbeddedDatabaseBuilder())
            .addScript("classpath:rewards/testdb/schema.sql")
            .addScript("classpath:rewards/testdb/test-data.sql")
            .build();
    }   
}

What exactly do? I think that all the beans configured in this class will belong to the jdbc-devprofile, but I am not sure about it. Can you give me more information about this thing?

具体做什么?我认为这个类中配置的所有bean都会属于jdbc-dev配置文件,但我不确定。你能给我更多关于这件事的信息吗?

Why I have to use the @Profileannotation on a **configuration class* instead annotate directly my beans?

为什么我必须在 **configuration class* 上使用@Profile批注而不是直接批注我的 bean?

Tnx

田纳西州

回答by Bohuslav Burghardt

If you look at the JavaDoc of ActiveProfilesannotation, it contains this text:

如果您查看ActiveProfiles注释的 JavaDoc ,它包含以下文本:

ActiveProfiles is a class-level annotation that is used to declare which active bean definition profiles should be used when loading an ApplicationContext for test classes.

ActiveProfiles 是一个类级别的注解,用于声明在为测试类加载 ApplicationContext 时应该使用哪些活动 bean 定义配置文件。

Meaning it is only supposed to be used to declare active Spring profiles for test classes. So If put it on a Configuration class it should have no effect.

这意味着它只应该用于为测试类声明活动的 Spring 配置文件。所以如果把它放在 Configuration 类上,它应该没有效果。

And as for the @Profileannotation, it can be used on both method and class level. If you use it on method annotated with @Beanin configuration class, only that bean will belong to the profile. If you use it on configuration class, it will be applied to all the beans within the configuration class, if you use it on @Componentclass, the profile will be applied to the bean represented by that class.

至于@Profile注解,它既可以用于方法级别,也可以用于类级别。如果您@Bean在配置类中使用它注释的方法上使用它,则只有该 bean 将属于配置文件。如果你在配置类上使用它,它将应用于配置类中的所有bean,如果你在@Component类上使用它,配置文件将应用于该类所代表的bean。

@Profileannotation JavaDocprovides more detailed explanation of these rules.

@Profile注释 JavaDoc对这些规则提供了更详细的解释。

Why I have to use the @Profile annotation on a **configuration class* instead annotate directly my beans?

为什么我必须在 **configuration class* 上使用 @Profile 批注而不是直接批注我的 bean?

Well if all beans in given configuration class should be active only for certain profile(s) then it makes sense to declare that globally on the configuration class to avoid having to individually specify the profile on all beans. But If you were to annotate all indiviudal beans it would work as well.

好吧,如果给定配置类中的所有 bean 应该仅对某些配置文件处于活动状态,那么在配置类上全局声明它以避免必须在所有 bean 上单独指定配置文件是有意义的。但是,如果您要注释所有单个 bean,它也会起作用。