
# Aware interfaces

A bean that implements an `*Aware` interface receives its own name, the bean factory, the context or another container object through a method call.

## Why

Constructor injection is usually simpler: a bean can inject `BeanFactory`, `ApplicationContext`, `Environment`, `ResourceLoader`, `ApplicationEventPublisher` or `MessageSource` directly. The aware interfaces are for the remaining cases:

- a bean that needs its own bean name, for example several beans of one class that each read their own settings;
- a base class shared by many beans, whose constructors you do not want to change;
- objects the container creates but does not inject: an `ImportSelector` or an `ImportBeanDefinitionRegistrar` can implement `EnvironmentAware`, `BeanFactoryAware` and `ResourceLoaderAware`, which are called before it runs;
- framework classes.

Each setter is called once, after injection and before the init callbacks (`@PostConstruct`, `afterPropertiesSet`, the init method). The order is:

1. `BeanNameAware.setBeanName`;
2. `BeanFactoryAware.setBeanFactory`;
3. `EnvironmentAware.setEnvironment`;
4. `EmbeddedValueResolverAware.setEmbeddedValueResolver`;
5. `ResourceLoaderAware.setResourceLoader`;
6. `ApplicationEventPublisherAware.setApplicationEventPublisher`;
7. `MessageSourceAware.setMessageSource`;
8. `ApplicationContextAware.setApplicationContext`.

The first two are called by the bean factory. The others are called by `ApplicationContextAwareProcessor`, a [BeanPostProcessor](bean-post-processor.md) that every context registers. A bare `DefaultListableBeanFactory` without a context calls only the first two.

## Example

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

abstract interface class Plugin {
  void run();
}

// Two workers of one class, registered as 'importer' and 'exporter'.
// Each reads its own settings, keyed by its bean name.
class Worker implements BeanNameAware, EnvironmentAware {
  late final String id;
  late final Environment _environment;

  @override
  void setBeanName(String name) => id = name;

  @override
  void setEnvironment(Environment environment) => _environment = environment;

  int get batchSize =>
      int.parse(_environment.getProperty('workers.$id.batch-size') ?? '100');
}

@Configuration()
class WorkerConfig {
  @Bean()
  Worker importer() => Worker();

  @Bean()
  Worker exporter() => Worker();
}

// Which plugin runs is decided by name at run time.
@Component()
class PluginLoader implements BeanFactoryAware {
  late BeanFactory _factory;

  @override
  void setBeanFactory(BeanFactory beanFactory) => _factory = beanFactory;

  void run(String name) => (_factory.getBeanByName(name) as Plugin).run();
}

// Paths built from properties, resolved at run time.
@Component()
class Paths implements EmbeddedValueResolverAware {
  late String cache;

  @override
  void setEmbeddedValueResolver(StringValueResolver resolver) {
    cache = resolver(r"#{'${app.home:/tmp}' + '/cache'}");
  }
}
```

## Members

| Interface | Method | Receives |
|---|---|---|
| `BeanNameAware` | `setBeanName(String name)` | The bean's name, never an alias. |
| `BeanFactoryAware` | `setBeanFactory(BeanFactory beanFactory)` | The factory that holds the bean. |
| `EnvironmentAware` | `setEnvironment(Environment environment)` | The context's environment. |
| `EmbeddedValueResolverAware` | `setEmbeddedValueResolver(StringValueResolver resolver)` | A function that resolves `${...}` placeholders, then `#{...}` expressions, like `@Value`. |
| `ResourceLoaderAware` | `setResourceLoader(ResourceLoader resourceLoader)` | The context, as resource loader. Custom protocols added to it work. |
| `ApplicationEventPublisherAware` | `setApplicationEventPublisher(ApplicationEventPublisher publisher)` | The context, as event publisher. |
| `MessageSourceAware` | `setMessageSource(MessageSource messageSource)` | The context, which looks messages up in the `messageSource` bean. |
| `ApplicationContextAware` | `setApplicationContext(ApplicationContext applicationContext)` | The context that created the bean. |

`Aware` is the common supertype. It has no methods.

## In Spring (Java)

```java
class Worker implements BeanNameAware, EnvironmentAware {
  String id;
  Environment environment;

  @Override public void setBeanName(String name) { id = name; }
  @Override public void setEnvironment(Environment env) { environment = env; }
}
```

Differences that matter:

- `StringValueResolver` is a function type: call `resolver(text)` instead of `resolver.resolveStringValue(text)`. `#{null}` gives an empty string.
- `BeanClassLoaderAware`, `ApplicationStartupAware` and `ServletContextAware` do not exist.

## See also

- [ApplicationContext](application-context.md)
- [Lifecycle and SmartLifecycle](lifecycle.md)
- [@PostConstruct](post-construct.md)
- [BeanPostProcessor](bean-post-processor.md)
- [@Import](import.md) (selectors and registrars)
- [Environment](../config/environment.md)
- [Placeholders](../config/placeholders.md)
