Что произойдет в Spring, если я использую аннотацию @ActiveProfiles в классе конфигурации вместо того, чтобы использовать ее в классе, который определяет мои bean-компоненты?

Я готовлюсь к сертификации Spring Core и у меня есть некоторые сомнения, связанные с использованием профилей в тестах JUnit.

Итак, я знаю, что если я отмечу класс следующим образом:

@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
    }
}

Я объявляю сервисный компонент, принадлежащий профилю заглушки.

Итак, если мой тестовый класс выглядит примерно так:

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

это означает, что будут использоваться bean-компоненты, принадлежащие профилю stub, и bean-компоненты, не имеющие профиля. Это правильно или я что-то упускаю?

Что произойдет, если вместо этого использовать аннотацию @ActiveProfiles для класса (экземпляром которого будет Spring bean), я использую ее в Класс конфигурации Java?

Что-то вроде этого:

@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();
    }   
}

Что именно делать? Я думаю, что все бины, настроенные в этом классе, будут принадлежать профилю jdbc-dev, но я не уверен в этом. Можете ли вы дать мне больше информации об этой вещи?

Почему я должен использовать аннотацию @Profile в **классе конфигурации* вместо того, чтобы аннотировать непосредственно мои bean-компоненты?

Tnx


person AndreaNobili    schedule 30.11.2014    source источник


Ответы (1)


Если вы посмотрите на JavaDoc ActiveProfiles, она содержит следующий текст:

ActiveProfiles — это аннотация на уровне класса, которая используется для объявления того, какие профили определений активных компонентов следует использовать при загрузке ApplicationContext для тестовых классов.

Это означает, что его предполагается использовать только для объявления активных профилей Spring для тестовых классов. Поэтому, если поместить его в класс конфигурации, это не должно иметь никакого эффекта.

А что касается аннотации @Profile, ее можно использовать как на уровне метода, так и на уровне класса. Если вы используете его в методе, аннотированном @Bean в классе конфигурации, только этот компонент будет принадлежать профилю. Если вы используете его в классе конфигурации, он будет применяться ко всем bean-компонентам в классе конфигурации, если вы используете его в классе @Component, профиль будет применяться к bean-компоненту, представленному этим классом.

@Profile аннотация JavaDoc содержит более подробное объяснение этих правил.

Почему я должен использовать аннотацию @Profile для **класса конфигурации* вместо того, чтобы аннотировать непосредственно мои bean-компоненты?

Хорошо, если все bean-компоненты в данном классе конфигурации должны быть активны только для определенных профилей, тогда имеет смысл объявить это глобально в классе конфигурации, чтобы избежать необходимости индивидуально указывать профиль для всех bean-компонентов. Но если бы вы аннотировали все отдельные bean-компоненты, это тоже сработало бы.

person Bohuslav Burghardt    schedule 30.11.2014