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

1. Обзор

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

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

2. Aware Интерфейс

И BeanNameAware , и BeanFactoryAware принадлежат интерфейсу корневого маркера org.springframework.beans.factory.Aware .

При этом используется установка сеттера для получения объекта во время запуска контекста приложения.

  • Интерфейс Aware представляет собой сочетание шаблонов обратного вызова, прослушивателя и наблюдателя ** . Это указывает на то, что компонент может быть уведомлен контейнером 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 , контейнер в этом случае назначит имя метода getMyBeanName () в bean-компонент. Таким образом, вывод будет «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 это может быть возможность использовать пружинный компонент из унаследованного кода.

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

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

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

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