
# @Profile

`@Profile([...])` registers a bean only when the active profiles match.

## Why

Profiles name the situations an application runs in: `dev`, `test`, `prod`, `eu`. They are activated with the `spring.profiles.active` property or `Environment.setActiveProfiles`.

Use `@Profile` to swap implementations between them: an in-memory mailer during development, a fake payment gateway in tests, the real ones in production. No `if` in `main`, and no test-only code path in the services.

Each entry is a profile expression:

- `'dev'`: the `dev` profile is active;
- `'!prod'`: the `prod` profile is not active;
- `'eu & (dev | test)'`: combinations with `&`, `|`, `!` and parentheses.

The bean is registered when **any** entry matches. On a configuration class, the profile applies to all its `@Bean` methods and to its `@PropertySource` files.

To name a set of profiles once, subclass `Profile`:

```dart
class Dev extends Profile {
  const Dev() : super(const ['dev']);
}
```

## Example

```dart
import 'package:spring_core_dart/spring_core_dart.dart';

abstract interface class Mailer {
  void send(String to, String text);
}

const log = SpringLog('mail');

// Development and tests: mails go to the log, nobody gets real mail.
@Component()
@Profile(['dev', 'test'])
class LogMailer implements Mailer {
  @override
  void send(String to, String text) => log.info('mail to $to: $text');
}

// Everywhere else.
@Component()
@Profile(['!dev & !test'])
class SmtpMailer implements Mailer {
  @override
  void send(String to, String text) {
    // talk to the SMTP server
  }
}
```

Activating a profile without Spring Boot:

```dart
void main() {
  final env = StandardEnvironment()..setActiveProfiles(['dev']);
  final context = ApplicationContext.run([appBeans], environment: env);
  context.getBean<Mailer>().send('ada@example.com', 'Hi'); // LogMailer
  context.close();
}
```

With configuration files, `spring.profiles.active=dev` in `application.properties` does the same.

## Parameters

| Name | Type | Default | Meaning |
|---|---|---|---|
| `value` (positional) | `List<String>` | required | Profile expressions. The bean is registered if any of them matches. |

## In Spring (Java)

```java
@Component
@Profile({"dev", "test"})
class LogMailer implements Mailer { ... }
```

Differences that matter:

- Spring accepts a single string; here the value is always a list.
- A malformed expression such as `(dev` or `a &` is refused here. Some Spring versions accept it.
- Custom profile annotations are subclasses of `Profile` instead of meta-annotations.

## See also

- [Profiles](../config/profiles.md)
- [Environment](../config/environment.md)
- [@Conditional](conditional.md)
- [@Fallback](fallback.md)
- [@PropertySource](../config/property-source.md)
