Перейти к основному содержимому

Интерфейсы BeanNameAware и BeanFactoryAware в Spring

· 3 мин. чтения

1. Обзор

В этом кратком руководстве мы сосредоточимся на интерфейсах BeanNameAware и BeanFactoryAware в Spring Framework .

Мы опишем каждый интерфейс отдельно с плюсами и минусами их использования.

2. Осведомленный интерфейс

И BeanNameAware, и BeanFactoryAware принадлежат интерфейсу корневого маркера org.springframework.beans.factory.Aware . Это использует инъекцию сеттера для получения объекта во время запуска контекста приложения.

Интерфейс Aware представляет собой смесь шаблонов проектирования обратного вызова, слушателя и наблюдателя . Это указывает на то, что bean-компонент может быть уведомлен контейнером Spring с помощью методов обратного вызова.

3. BeanNameAware

BeanNameAware сообщает объекту об имени компонента, определенном в контейнере .

Давайте посмотрим на пример:

public class MyBeanName implements BeanNameAware {

@Override
public void setBeanName(String beanName) {
System.out.println(beanName);
}
}

Свойство beanName представляет идентификатор компонента, зарегистрированный в контейнере Spring. В нашей реализации мы просто отображаем имя компонента.

Далее давайте зарегистрируем bean-компонент этого типа в классе конфигурации Spring:

@Configuration
public class Config {

@Bean(name = "myCustomBeanName")
public MyBeanName getMyBeanName() {
return new MyBeanName();
}
}

Здесь мы явно присвоили имя нашему классу MyBeanName с помощью строки @Bean(name = «myCustomBeanName») .

Теперь мы можем запустить контекст приложения и получить из него бин:

AnnotationConfigApplicationContext context 
= new AnnotationConfigApplicationContext(Config.class);

MyBeanName myBeanName = context.getBean(MyBeanName.class);

Как и следовало ожидать, метод setBeanName выводит «myCustomBeanName» .

Если мы удалим код name = «…» из аннотации @Bean , контейнер, в этом случае, присвоит bean-компоненту имя метода getMyBeanName() . Таким образом, вывод будет «getMyBeanName» .

4. BeanFactoryAware

BeanFactoryAware используется для внедрения объекта BeanFactory . Таким образом мы получаем доступ к BeanFactory , которая создала объект.

Вот пример класса MyBeanFactory :

public class MyBeanFactory implements BeanFactoryAware {

private BeanFactory beanFactory;

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}

public void getMyBeanName() {
MyBeanName myBeanName = beanFactory.getBean(MyBeanName.class);
System.out.println(beanFactory.isSingleton("myCustomBeanName"));
}
}

С помощью метода setBeanFactory() мы присваиваем ссылку BeanFactory из контейнера IoC свойству beanFactory .

После этого мы можем использовать его напрямую, как в функции getMyBeanName() .

Давайте инициализируем MyBeanFactory и вызовем метод getMyBeanName() :

MyBeanFactory myBeanFactory = context.getBean(MyBeanFactory.class);
myBeanFactory.getMyBeanName();

Поскольку мы уже создали экземпляр класса MyBeanName в предыдущем примере, Spring вызовет здесь существующий экземпляр.

Строка beanFactory.isSingleton(“myCustomBeanName”) подтверждает это.

5. Когда использовать?

Типичным вариантом использования BeanNameAware может быть получение имени компонента для регистрации или подключения. Для BeanFactoryAware это может быть возможность использовать Spring bean из устаревшего кода.

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

6. Заключение

В этой статье мы узнали об интерфейсах BeanNameAware и BeanFactoryAware и о том, как их использовать на практике.

Как обычно, полный код для этой статьи доступен на GitHub .