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 .