В этой статье рассказывается, как создавать и активировать профили Spring различными способами.
Spring Boot Profiles
Для начала рассмотрим, как создавать профили в Spring Boot и делать профиль активным с помощью файла application.properties.
За основу возьмем Spring Boot REST API приложение, написанное в статье.
Только теперь будем использовать не встроенную базу данных, а базу MySQL. Создадим в ней три схемы для трех окружений — development, test и production. Не забудьте включить соответствующую Maven-зависимость (либо можно скачать код готового приложения):
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
В нашем приложении будет соответственно три профиля. Назовем их dev, test и prod.
Активный профиль задается в файле application.properties:
spring.profiles.active=dev
Для каждого профиля создадим соотвествующий файл:
- application-dev.properties
- application-test.properties
- application-prod.properties
В каждом из них будут свои настройки базы данных. Например, в файле application-test.properties они будут такими:
spring.datasource.url=jdbc:mysql://localhost:3306/test_database_name spring.datasource.username=root spring.datasource.password=admin spring.jpa.hibernate.ddl-auto=create
В файле application-dev.properties они такие:
spring.datasource.url=jdbc:mysql://localhost:3306/dev_database_name spring.datasource.username=root spring.datasource.password=admin spring.jpa.hibernate.ddl-auto=create
Теперь давайте запустим наше REST-приложение. Поскольку в application.properties стоит активация профиля dev, DataSource будет инициализироваться настройками файла application-dev.properties, то есть использоваться будет база данных dev_database_name. В этом можно убедиться, добавив Person в базу с помощью запроса через Postman и посмотрев, что таблица Person не пуста в базе dev_database_name. Как это делать, мы показывали в предыдущей статье.
Теперь попробуем активировать профиль для интеграционного теста. Тесты мы писали с помощью REST-assured.
Активация профиля для тестирования
Тестировочный профиль активируется с помощью аннотации @ActiveProfiles(«test»):
@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class PersonControllerTest {
@LocalServerPort
private int port;
@Autowired
private PersonRepository repository;
@Before
public void setup() {
RestAssured.port = port;
}
@After
public void resetDb() {
repository.deleteAll();
repository.flush();
}
@Test
public void whenCreatePerson_thenStatus201() {
Person person = new Person("Michail");
given().log().body()
.contentType("application/json").body(person)
.when().post("/persons")
.then().log().body()
.statusCode(HttpStatus.CREATED.value());
}
//остальные тесты
private Person createTestPerson(String name) {
Person emp = new Person(name);
return repository.saveAndFlush(emp);
}
}
Просто, не правда ли?
Но это еще не все, далее мы рассмотрим как содавать для каждого профиля свои бины с помощью аннотаций.
Использование аннотации @Profile
Допустим, нам нужно создавать определенный бин только для определенного профиля. Для этого можно аннотировать бин с помощью @Profile. Аннотация применима как к классу, так и к методу.
Давайте аннотируем класс ExampleTestBean, экземпляр которого будет создаваться только при активном профиле test:
@Profile("test")
@Component
public class ExampleTestBean {
}
Проверим, что бин действительно создается. Мы активировали профиль test, внедрили бин ExampleTestBean и проверили, что он не нулевой:
@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProfilesIntegrationTest {
@Autowired
Environment environment;
@Autowired
ExampleTestBean testBean;
@Test
public void testSpringProfiles() {
for (final String profileName : environment.getActiveProfiles()) {
System.out.println("Currently active profile - " + profileName);
}
Assert.assertEquals("test", environment.getActiveProfiles()[0]);
assertNotNull(testBean);
}
}
Как получить активный профиль программно
Обратите внимание, что в предыдущем примере мы взяли и напечатали текущий активный профиль:
for (final String profileName : environment.getActiveProfiles()) {
System.out.println("Currently active profile - " + profileName);
}
Environment просто внедрен с помощью @Autowire.
Цикл используется потому, что активных профилей может быть несколько. У нас он один, так что берем и печатаем самый первый.
Итог
Настройка профилей в Spring и Spring Boot оказалась легкой.
Как всегда, полный код примера доступен на GitHub.