Как работают профили (Profiles) в Spring?

Ответ

Профили (Profiles) в Spring — это механизм условной регистрации бинов и конфигураций в зависимости от целевого окружения (development, test, production).

Объявление бина для конкретного профиля:

@Configuration
@Profile("dev") // Будет активен только при включённом профиле "dev"
public class DevDataSourceConfig {
    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .build(); // H2 для разработки
    }
}

@Configuration
@Profile("prod")
public class ProdDataSourceConfig {
    @Bean
    public DataSource dataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:postgresql://prod-host/db");
        // ... настройка пула соединений для продакшена
        return new HikariDataSource(config);
    }
}

Способы активации профилей:

  1. В application.properties/application.yml:
    spring.profiles.active=dev,debug
  2. Переменная окружения или аргумент командной строки:
    java -jar app.jar --spring.profiles.active=prod
    export SPRING_PROFILES_ACTIVE=prod
  3. Программно:
    SpringApplication.setAdditionalProfiles("test");
  4. В тестах с помощью аннотации @ActiveProfiles("test").

Дополнительно: Можно использовать аннотацию @Profile на уровне метода @Bean. Профили могут быть отрицательными с использованием !, например, @Profile("!prod").

Ответ 18+ 🔞

А, профили в Спринге! Ну это ж, блядь, как у тебя разные костюмы на разные случаи жизни. В трусах дома ходишь, в пиджаке на работу, а в смокинге — ну, если вдруг на бал, сука, позовут. Вот и тут так же.

Смотри, есть у тебя приложение. На компе у себя ты его запускаешь — там тебе база данных H2, чтоб не заморачиваться. А на сервере в продакшене — там уже серьёзная PostgreSQL, с пулом соединений и прочей хуйнёй. Так вот, чтобы один и тот же код не превращался в сраный винегрет из условий if (env == "prod"), придумали эти самые профили.

Как это выглядит, ёпта:

Вот ты объявляешь два конфига. Один для разработки (dev), другой для прода (prod). И говоришь Спрингу: «Слушай, дружище, если мы в dev — бери вот этот бин. Если в prod — ну ты понял, другой».

@Configuration
@Profile("dev") // Этот кусок кода оживет только когда профиль "dev" активен
public class DevDataSourceConfig {
    @Bean
    public DataSource dataSource() {
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .build(); // Просто H2, чтоб быстро и без геморроя
    }
}

@Configuration
@Profile("prod") // А этот — когда в бой идём
public class ProdDataSourceConfig {
    @Bean
    public DataSource dataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:postgresql://prod-host/db");
        // ... тут настраиваешь пул соединений, логины, пароли — всю эту ебучую продуктивизацию
        return new HikariDataSource(config);
    }
}

Красота, да? Никаких if-ов. Чистая магия, блядь.

А как сказать Спрингу, какой профиль сейчас в моде?

Вариантов — овердохуища:

  1. Прописать в application.properties — самый простой способ, для ленивых (как я).

    spring.profiles.active=dev,debug  // Можно и несколько, через запятую
  2. Через командную строку — когда запускаешь уже собранный jar.

    java -jar my-app.jar --spring.profiles.active=prod

    Или через переменную окружения, если ты, блядь, настоящий девопс:

    export SPRING_PROFILES_ACTIVE=prod
  3. Программно, из кода — ну, если ты любишь всё усложнять.

    SpringApplication.setAdditionalProfiles("test");
  4. В тестах — там вообще отдельная песня. Вешаешь над классом теста аннотацию @ActiveProfiles("test"), и он поднимает контекст именно с тестовыми бинами. Удобно, ебать.

А ещё есть фишки, блядь!

Можно вешать @Profile не на весь класс-конфиг, а на отдельный метод с @Bean. Можно делать отрицательные профили типа @Profile("!prod") — что значит «активен везде, кроме продакшена». Это когда тебе нужен бин для всего, кроме одного ебучого случая.

В общем, профили — это, блядь, must have, чтобы не смешивать в одном котле настройки для разных сред. Без них — пипец и пиздец, а с ними — красота и порядок. Ну, почти порядок.