BeanFactory против ApplicationContext - PullRequest
       103

BeanFactory против ApplicationContext

217 голосов
/ 28 октября 2008

Я довольно новичок в Spring Framework, я играл с ним и собирал несколько примеров приложений для оценки Spring MVC для использования в будущем проекте компании. Пока что мне действительно нравится то, что я вижу в Spring MVC, оно кажется очень простым в использовании и побуждает вас писать классы, которые очень удобны для модульных тестов.

В качестве упражнения я пишу основной метод для одного из моих примеров / тестовых проектов. Одна вещь, о которой я неясен, это точные различия между BeanFactory и ApplicationContext - что подходит для использования в каких условиях?

Я понимаю, что ApplicationContext расширяет BeanFactory, но если я просто пишу простой основной метод, нужна ли мне дополнительная функциональность, предоставляемая ApplicationContext? И какой именно дополнительный функционал предоставляет ApplicationContext?

В дополнение к ответу "что я должен использовать в методе main ()", существуют ли какие-либо стандарты или рекомендации относительно того, какую реализацию мне следует использовать в таком сценарии? Должен ли мой метод main () быть написан так, чтобы он зависел от конфигурации компонента / приложения в формате XML - это безопасное предположение или я блокирую пользователя на что-то конкретное?

И изменится ли этот ответ в веб-среде - если кому-то из моих классов нужно было знать о Spring, им, скорее всего, понадобится ApplicationContext?

Спасибо за любую помощь. Я знаю, что многие из этих вопросов, вероятно, даны в справочном руководстве, но мне трудно найти четкую разбивку этих двух интерфейсов и плюсов / минусов каждого без прочтения руководства с помощью расчески с мелкими зубьями.

Ответы [ 19 ]

198 голосов
/ 28 октября 2008

Весенние документы хороши в этом: 3.8.1. BeanFactory или ApplicationContext? . У них есть таблица со сравнением, выложу фрагмент:

Фабрика бобов

  • Реализация / сборка бобов

Контекст приложения

  • Реализация / подключение бинов
  • Автоматическая регистрация BeanPostProcessor
  • Автоматическая регистрация BeanFactoryPostProcessor
  • Удобный доступ к источнику сообщений (для i18n)
  • ApplicationEvent публикация

Поэтому, если вам нужны какие-либо из пунктов, представленных на стороне контекста приложения, вы должны использовать ApplicationContext.

46 голосов
/ 28 февраля 2010

Мне кажется, что основная разница в выборе BeanFactory вместо ApplicationContext заключается в том, что ApplicationContext будет предварительно создавать все компоненты. От Весна Документы :

Spring устанавливает свойства и разрешает зависимости как можно позже, когда бин действительно создается. Это означает, что контейнер Spring, который был загружен правильно, может позже сгенерировать исключение при запросе объекта, если возникла проблема с созданием этого объекта или одной из его зависимостей. Например, бин генерирует исключение в результате отсутствия или недопустимого свойства. Эта потенциально задержанная видимость некоторых проблем конфигурации является причиной того, что реализации ApplicationContext по умолчанию предварительно создают одноэлементные компоненты. За счет некоторого времени и памяти, необходимых для создания этих bean-компонентов до того, как они действительно понадобятся, вы обнаружите проблемы конфигурации при создании ApplicationContext, а не позднее. Вы по-прежнему можете переопределить это поведение по умолчанию, чтобы синглтон-бины выполнялись с отложенной инициализацией, а не с предварительной реализацией.

Учитывая это, я изначально выбрал BeanFactory для использования в интеграционных тестах / тестах производительности, поскольку не хотел загружать все приложение для тестирования изолированных bean-компонентов. Однако - и кто-то поправит меня, если я ошибаюсь - BeanFactory не поддерживает classpath XML-конфигурацию. Таким образом, BeanFactory и ApplicationContext каждый обеспечивает важную функцию, которую я хотел, но ни один не сделал оба.

Насколько я могу судить, примечание в документации о переопределении поведения экземпляра по умолчанию происходит в конфигурации, и это для каждого компонента, поэтому я не могу просто установить атрибут "lazy-init" в файле XML или Я застрял, поддерживая его версию для тестирования и одну для развертывания.

В итоге я расширил ClassPathXmlApplicationContext, чтобы лениво загружать bean-компоненты для использования в таких тестах:

public class LazyLoadingXmlApplicationContext extends ClassPathXmlApplicationContext {

    public LazyLoadingXmlApplicationContext(String[] configLocations) {
        super(configLocations);
    }

    /**
     * Upon loading bean definitions, force beans to be lazy-initialized.
     * @see org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
     */

    @Override
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
        super.loadBeanDefinitions(reader);
        for (String name: reader.getBeanFactory().getBeanDefinitionNames()) {
            AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) reader.getBeanFactory().getBeanDefinition(name);
            beanDefinition.setLazyInit(true);
        }
    }

}
38 голосов
/ 20 января 2016

Spring предоставляет два вида контейнера IOC, один - XMLBeanFactory, а другой - ApplicationContext.

+---------------------------------------+-----------------+--------------------------------+
|                                       | BeanFactory     |       ApplicationContext       |
+---------------------------------------+-----------------+--------------------------------+
| Annotation support                    | No              | Yes                            |
| BeanPostProcessor Registration        | Manual          | Automatic                      |
| implementation                        | XMLBeanFactory  | ClassPath/FileSystem/WebXmlApplicationContext|
| internationalization                  | No              | Yes                            |
| Enterprise services                   | No              | Yes                            |
| ApplicationEvent publication          | No              | Yes                            |
+---------------------------------------+-----------------+--------------------------------+

enter image description here

  • FileSystemXmlApplicationContext Бины загружаются по полному пути.
  • ClassPathXmlApplicationContext Бобы, загруженные через CLASSPATH
  • XMLWebApplicationContext и AnnotationConfigWebApplicationContext bean-компоненты, загружаемые через контекст веб-приложения.
  • AnnotationConfigApplicationContext Загрузка Spring bean-компонентов из конфигурации на основе аннотаций.

пример:

  ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
  • ApplicationContext - это контейнер, инициализированный ContextLoaderListener или ContextLoaderServlet, определенным в web.xml и ContextLoaderPlugin, определенным в struts-config.xml.

Примечание : XmlBeanFactory равно устарело по состоянию на весну 3.1 в пользу DefaultListableBeanFactory и XmlBeanDefinitionReader.

29 голосов
/ 28 октября 2008

Чтобы добавить ответ на вопрос Мигеля Пинга, есть еще один раздел из документации , который также отвечает на этот вопрос:

Короткая версия: используйте ApplicationContext, если у вас нет веских причин не делать этого. Для тех из вас, кто ищет немного больше глубины в отношении «но почему» вышеприведенной рекомендации, продолжайте читать.

(опубликовать это для любых будущих новичков Spring, которые могут прочитать этот вопрос)

17 голосов
/ 27 февраля 2010
  1. ApplicationContext является более предпочтительным способом, чем BeanFactory

  2. В новых версиях Spring BeanFactory заменено на ApplicationContext. Но все же BeanFactory существует для обратной совместимости

  3. ApplicationContext extends BeanFactory и имеет следующие преимущества
    • поддерживает интернационализацию текстовых сообщений
    • поддерживает публикацию событий для зарегистрированных слушателей
    • доступ к ресурсам, таким как URL и файлы
12 голосов
/ 04 ноября 2008

Я думаю, что лучше всегда использовать ApplicationContext, если вы не находитесь в мобильной среде, как уже сказал кто-то другой. ApplicationContext обладает большей функциональностью, и вы определенно хотите использовать PostProcessor, такие как RequiredAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor и CommonAnnotationBeanPostProcessor, которые помогут вам упростить ваши файлы конфигурации Spring, и вы можете использовать аннотации, такие как @Required, @ BeansConnect, @PostConstruct, .

Даже если вы не используете все, что предлагает ApplicationContext, лучше использовать его в любом случае, а потом, если вы решите использовать некоторые ресурсы, такие как сообщения или постпроцессоры, или другую схему для добавления транзакционных советов и таким образом, у вас уже будет ApplicationContext, и вам не нужно будет менять код.

Если вы пишете отдельное приложение, загрузите ApplicationContext в свой метод main, используя ClassPathXmlApplicationContext, и получите основной компонент и вызовите его run () (или любой другой метод) для запуска приложения. Если вы пишете веб-приложение, используйте ContextLoaderListener в файле web.xml, чтобы он создавал ApplicationContext, и позже вы можете получить его из ServletContext, независимо от того, используете ли вы JSP, JSF, JSTL, стойки, Tapestry и т. Д. .

Кроме того, помните, что вы можете использовать несколько файлов конфигурации Spring и вы можете создать ApplicationContext, перечислив все файлы в конструкторе (или перечислив их в context-param для ContextLoaderListener), или вы можете просто загрузить основную конфигурацию файл, который имеет операторы импорта. Вы можете импортировать файл конфигурации Spring в другой файл конфигурации Spring, используя , что очень полезно, когда вы программно создаете ApplicationContext в основном методе и загружаете только один файл конфигурации Spring.

10 голосов
/ 04 июня 2013

ApplicationContext: Он загружает Spring Bean, сконфигурированные в файле конфигурации Spring, и управляет жизненным циклом Spring Bean, как и КОГДА НАЧИНАЕТСЯ КОНТЕЙНЕР. Он не будет ждать, пока не будет вызван getBean ("springbeanref") .

BeanFactory Он загружает Spring Bean, сконфигурированные в файле конфигурации Spring, управляет жизненным циклом Spring Bean, когда мы вызываем getBean ("springbeanref") . Так, когда мы вызываем getBean ("springbeanref") во время весеннего жизненного цикла бобов.

6 голосов
/ 29 октября 2008

В большинстве случаев ApplicationContext предпочтительнее, если вам не нужно экономить ресурсы, как в мобильном приложении.

Я не уверен относительно зависимости от формата XML, но я почти уверен, что наиболее распространенными реализациями ApplicationContext являются такие XML, как ClassPathXmlApplicationContext, XmlWebApplicationContext и FileSystemXmlApplicationContext. Это единственные три, которые я когда-либо использовал.

Если вы разрабатываете веб-приложение, можно с уверенностью сказать, что вам нужно использовать XmlWebApplicationContext.

Если вы хотите, чтобы ваши bean-компоненты знали о Spring, вы можете сделать так, чтобы они реализовали BeanFactoryAware и / или ApplicationContextAware, так что вы можете использовать BeanFactory или ApplicationContext и выбрать, какой интерфейс реализовать.

5 голосов
/ 01 октября 2017

Разница между BeanFactory и ApplicationContext заключается в следующем:

  1. BeanFactory использует отложенную инициализацию , но ApplicationContext использует готовую инициализацию. В случае BeanFactory, bean-компонент создается при вызове метода getBeans (), но bean-компонент создается заранее в случае ApplicationContext при создании объекта ApplicationContext.
  2. BeanFactory явно предоставляет объект ресурса, используя синтаксис , но ApplicationContext создает и управляет объектами ресурса самостоятельно.
  3. BeanFactory не поддерживает интернационализацию , но ApplicationContext поддерживает интернационализацию.
  4. В BeanFactory внедрение зависимостей на основе аннотаций не поддерживается , но внедрение зависимостей на основе аннотаций поддерживается в ApplicationContext.

Использование BeanFactory:

BeanFactory beanfactory = new XMLBeanFactory(new FileSystemResource("spring.xml")); Triangle triangle =(Triangle)beanFactory.getBean("triangle");

Использование ApplicationContext:

ApplicationContext context = new ClassPathXMLApplicationContext("spring.xml") Triangle triangle =(Triangle)beanFactory.getBean("triangle");

5 голосов
/ 15 января 2016

BeanFactory и ApplicationContext оба способа получения бобов из вашего контейнера IOC , но все же есть некоторая разница.

BeanFactory - это фактический контейнер, который создает, конфигурирует и управляет несколькими компонентами bean. Эти бины, как правило, взаимодействуют друг с другом и, таким образом, имеют зависимости между собой. Эти зависимости отражены в данных конфигурации, используемых BeanFactory.

BeanFactory и ApplicationContext оба являются интерфейсами Java, а ApplicationContext расширяет BeanFactory. Оба они конфигурируются с использованием XML-файлов конфигурации. Короче говоря, BeanFactory предоставляет базовые функции управления инверсией ( IoC ) и внедрения зависимостей ( DI ), в то время как ApplicationContext предоставляет расширенные функции.

BeanFactory представлен интерфейсом " org.springframework.beans.factory " где BeanFactory, для которого существует несколько реализаций.

ClassPathResource resource = new ClassPathResource("appConfig.xml");
XmlBeanFactory factory = new XmlBeanFactory(resource);

РАЗНИЦА

  1. BeanFactory создание экземпляра bean-компонента при вызове getBean () , в то время как ApplicationContext создает экземпляр Singleton-компонента при запуске контейнера. Он не ожидает вызова getBean () .

  2. BeanFactory не обеспечивает поддержку интернационализации, но ApplicationContext обеспечивает ее поддержку.

  3. Еще одно отличие между BeanFactory против ApplicationContext заключается в возможности публиковать события в bean-компонентах, которые зарегистрированы как слушатели.

  4. Одной из популярных реализаций интерфейса BeanFactory является XMLBeanFactory , а одной из популярных реализаций интерфейса ApplicationContext является ClassPathXmlApplicationContext .

  5. Если вы используете автоматическое подключение и BeanFactory , вам нужно зарегистрировать AutoWiredBeanPostProcessor с помощью API, который можно настроить в XML, если вы используете ApplicationContext . В итоге BeanFactory подходит для тестирования и непроизводственного использования, но ApplicationContext является более многофункциональной реализацией контейнера и его следует отдавать предпочтению перед BeanFactory

  6. BeanFactory по умолчанию его поддержка Ленивый загрузка и ApplicationContext поддержка по умолчанию Агрессивный загрузка.

...