Spring IoC контейнер: BeanFactory или ApplicationContext
В этом посте объясняются различия между уровнями контейнеров BeanFactory и ApplicationContext и их влияние на загрузку.
Вам следует использовать ApplicationContext, если у вас нет веских причин для этого, с GenericApplicationContext и его подклассом AnnotationConfigApplicationContext в качестве общих реализаций для настраиваемой начальной загрузки. Это основные точки входа в основной контейнер Spring для всех общих целей: загрузка файлов конфигурации, запуск сканирования пути к классам, программная регистрация определений компонентов и аннотированных классов и (начиная с версии 5.0) регистрация определений функциональных компонентов.
Поскольку ApplicationContext включает в себя все функциональные возможности BeanFactory, его обычно рекомендуется использовать вместо простого BeanFactory, за исключением сценариев, где необходим полный контроль над обработкой bean-компонентов. Внутри ApplicationContext (например, реализации GenericApplicationContext) несколько видов bean-компонентов обнаруживаются по соглашению (то есть по имени bean-компонента или по типу bean-компонента - в частности, постпроцессорам), в то время как простой DefaultListableBeanFactory не зависит от каких-либо специальных bean-компонентов.
Для многих расширенных функций контейнера, таких как обработка аннотаций и проксирование AOP, важна точка расширения BeanPostProcessor. Если вы используете только обычный DefaultListableBeanFactory, такие постпроцессоры не обнаруживаются и не активируются по умолчанию. Эта ситуация может сбивать с толку, потому что на самом деле с вашей конфигурацией bean-компонента все в порядке. Скорее, в таком сценарии контейнер должен быть полностью загружен с помощью дополнительной настройки.
В следующей таблице перечислены функции, предоставляемые интерфейсами и реализациями BeanFactory и ApplicationContext.
Функция | BeanFactory |
ApplicationContext |
---|---|---|
Создание экземпляра компонента/подключение | Да | Да |
Интегрированное управление жизненным циклом | Нет | Да |
Автоматическая регистрация BeanPostProcessor | Нет | Да |
Автоматическая регистрация BeanFactoryPostProcessor | Нет | Да |
Удобный доступ к MessageSource (для интернализации) | Нет | Да |
Встроенный механизм публикации ApplicationEvent | Нет | Да |
Чтобы явно зарегистрировать постпроцессор bean-компонента в DefaultListableBeanFactory, вам необходимо программно вызвать addBeanPostProcessor, как показано в следующем примере:
Java
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// заполняем фабрику определениями bean-компонентов
// теперь регистрируем все необходимые экземпляры BeanPostProcessor
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
factory.addBeanPostProcessor(new MyBeanPostProcessor());
// теперь начинаем использовать фабрику
Kotlin
val factory = DefaultListableBeanFactory()
// заполняем фабрику определениями bean-компонентов
// теперь регистрируем все необходимые экземпляры BeanPostProcessor
factory.addBeanPostProcessor(AutowiredAnnotationBeanPostProcessor())
factory.addBeanPostProcessor(MyBeanPostProcessor())
// теперь начинаем использовать фабрику
Чтобы применить BeanFactoryPostProcessor к простому DefaultListableBeanFactory, вам необходимо вызвать его метод postProcessBeanFactory, как показано в следующем примере:
Java
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));
// вводим некоторые значения свойств из файла Properties
PropertySourcesPlaceholderConfigurer cfg = new PropertySourcesPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
// теперь фактически делаем замену
cfg.postProcessBeanFactory(factory);
Kotlin
val factory = DefaultListableBeanFactory()
val reader = XmlBeanDefinitionReader(factory)
reader.loadBeanDefinitions(FileSystemResource("beans.xml"))
// вводим некоторые значения свойств из файла Properties
val cfg = PropertySourcesPlaceholderConfigurer()
cfg.setLocation(FileSystemResource("jdbc.properties"))
// теперь фактически делаем замену
cfg.postProcessBeanFactory(factory)
В обоих случаях явные шаги регистрации неудобны, поэтому различные варианты ApplicationContext предпочтительнее простого DefaultListableBeanFactory в приложениях с поддержкой Spring, особенно при использовании экземпляров BeanFactoryPostProcessor и BeanPostProcessor для расширенных функций контейнера в типичной корпоративной настройке.
AnnotationConfigApplicationContext имеет все зарегистрированные постпроцессоры общих аннотаций и может вводить дополнительные процессоры под крышками через аннотации конфигурации, такие как @EnableTransactionManagement. На уровне абстракции модели конфигурации Spring, основанной на аннотациях, понятие постпроцессоров компонентов становится простой внутренней деталью контейнера.
Читайте также:
- Spring IoC контейнер: дополнительные возможности ApplicationContext, развертывание Spring ApplicationContext как файла RAR Java EE
- Spring IoC контейнер: BeanFactory
- Spring IoC контейнер: дополнительные возможности ApplicationContext, удобный доступ к низкоуровневым ресурсам
Комментарии
Отправить комментарий