Вопрос

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

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

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

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

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

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

Это было полезно?

Решение

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

Фасолевый завод

  • Создание экземпляра/связывание bean-компонента

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

  • Создание экземпляра/связывание bean-компонента
  • Автоматическая регистрация BeanPostProcessor
  • Автоматическая регистрация BeanFactoryPostProcessor
  • Удобный доступ к MessageSource (для i18n)
  • Публикация ApplicationEvent

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

Другие советы

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

  

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

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

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

В итоге я расширил <=>, чтобы лениво загружать 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);
        }
    }

}

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 Загрузка bean-компонентов Spring из конфигурации на основе аннотаций.

пример:

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

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

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

  

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

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

  1. ApplicationContext является более предпочтительным способом, чем BeanFactory

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

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

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

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

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

Кроме того, помните, что вы можете использовать несколько файлов конфигурации Spring и вы можете создать ApplicationContext, перечислив все файлы в конструкторе (или перечислив их в context-param для ContextLoaderListener), или вы можете просто загрузить основную конфигурацию файл, который имеет операторы импорта. Вы можете импортировать файл конфигурации Spring в другой файл конфигурации Spring, используя & Lt; import resource = & Quot; otherfile.xml & Quot; / GT &; что очень полезно, когда вы программно создаете ApplicationContext в методе main и загружаете только один конфигурационный файл Spring.

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

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

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

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

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

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

БинФабрика и Контекст приложения оба способа получить бобы из источника МОК контейнер, но все же есть некоторая разница.

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

БинФабрика и Контекст приложения оба являются интерфейсами Java, а ApplicationContext расширяет BeanFactory.Оба они настраиваются с использованием файлов конфигурации XML.Короче говоря, BeanFactory обеспечивает базовую инверсию управления (МОК) и внедрение зависимостей (ДИ) функции, в то время как ApplicationContext предоставляет передовой функции.

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

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

РАЗНИЦА

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

  2. БинФабрика не обеспечивает поддержку интернационализации, но Контекст приложения обеспечивает его поддержку.

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

  4. Одна из популярных реализаций БинФабрика интерфейс XMLBeanFactory хотя одна из популярных реализаций Контекст приложения интерфейс Класспасксмлаппликионконтекст.

  5. Если вы используете автоматическую проводку и используете БинФабрика чем вам нужно зарегистрироваться AutoWiredBeanПостпроцессор используя API, который вы можете настроить в XML, если используете Контекст приложения.В итоге БинФабрика подходит для тестирования и непроизводственного использования, но Контекст приложения является более многофункциональной реализацией контейнера, и ей следует отдавать предпочтение БинФабрика

  6. БинФабрика по умолчанию его поддержка Ленивый погрузка и Контекст приложения поддержка по умолчанию агрессивный загрузка.

Разница между БинФабрика и Контекст приложения следующие:

  1. BeanFactory использует ленивую инициализацию но ApplicationContext использует быструю инициализацию.В случае BeanFactory компонент создается при вызове метода getBeans(), но в случае 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 context = new ClassPathXMLApplicationContext("spring.xml") Triangle triangle =(Triangle)beanFactory.getBean("triangle");

Функциональная матрица Bean Factory и контекст приложения источник из весенних документов

 введите описание изображения здесь

Снимок экрана функций BeanFacotry и ApplicationContext

По сути, мы можем создать объект-контейнер Spring двумя способами.

  1. использование BeatFactory
  2. использование контекста приложения

оба являются интерфейсами

используя классы реализации, мы можем создать объект для контейнера Spring

подходя к разногласиям

БинФабрика

  1. Не поддерживает внедрение зависимостей на основе аннотаций.

  2. Не поддерживает I18N

  3. По умолчанию поддерживается отложенная загрузка.

  4. он не позволяет настраивать несколько файлов конфигурации.

бывший:BeanFactory context=new XmlBeanFactory(new Resource("applicationContext.xml"));

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

  1. Поддержка внедрения зависимостей на основе аннотаций.-@Autowired, @PreDestroy

  2. Поддержка I18N

  3. По умолчанию он поддерживает агрессивную загрузку.

  4. это позволяет настроить несколько файлов конфигурации.

бывший:
Контекст ApplicationContext = новый ClasspathXmlApplicationContext («applicationContext.xml»);

а.Одно из различий между фабрикой компонентов и контекстом приложения заключается в том, что в первом случае создается экземпляр компонента только при вызове метода getBean(), тогда как ApplicationContext создает экземпляр компонента Singleton при запуске контейнера. Он не ждет вызова getBean.

б.

ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

или

ApplicationContext context = new ClassPathXmlApplicationContext{"spring_dao.xml","spring_service.xml};

Вы можете использовать один или несколько XML-файлов в зависимости от требований вашего проекта.Поскольку я здесь использую два XML-файла, т.е.один для сведений о конфигурации для классов обслуживания, другой для классов dao.Здесь ClassPathXmlApplicationContext является дочерним элементом ApplicationContext.

в.Контейнер BeanFactory — это базовый контейнер, он может только создавать объекты и внедрять зависимости.Но мы не можем подключить другие службы, такие как безопасность, транзакции, обмен сообщениями и т. д.для предоставления всех услуг мы должны использовать контейнер ApplicationContext.

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

е.Контейнер BeanFactory не поддерживает функцию автоматического сканирования (поддержка внедрения зависимостей на основе аннотаций), но контейнер ApplicationContext поддерживает.

ф.Контейнер Beanfactory не будет создавать объект bean-компонента до момента запроса.Это означает, что Beanfactory Container лениво загружает bean-компоненты.В то время как ApplicationContext Container создает объекты Singleton bean только во время загрузки.Это значит, что идет ранняя загрузка.

г.Контейнер Beanfactory поддерживает только две области действия bean-компонентов (синглтон и прототип).Но контейнер ApplicationContext поддерживает всю область действия bean-компонентов.

Обратитесь к этому документу из Spring Docs:

http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#context-introduction-ctx-vs-beanfactory

5.15.1 BeanFactory или ApplicationContext?

Используйте ApplicationContext, если у вас нет веских причин для этого.

Поскольку ApplicationContext включает в себя все функциональные возможности BeanFactory, его обычно рекомендуют использовать поверх BeanFactory, за исключением нескольких ситуаций, например, в апплете, где потребление памяти может быть критическим и несколько дополнительных килобайт могут иметь значение. Однако для большинства типичных корпоративных приложений и систем ApplicationContext - это то, что вы хотите использовать. В Spring 2.0 и более поздних версиях интенсивно используется точка расширения BeanPostProcessor (для осуществления проксирования и т. Д.). Если вы используете только обычный BeanFactory, достаточное количество поддержки, такой как транзакции и AOP, не вступят в силу, по крайней мере, без каких-либо дополнительных шагов с вашей стороны. Эта ситуация может сбить с толку, потому что на самом деле все в порядке с конфигурацией.

ApplicationContext - это старший брат BeanFactory, и это все, что предлагает BeanFactory, а также многое другое.

В дополнение к стандартным возможностям жизненного цикла org.springframework.beans.factory.BeanFactory реализации ApplicationContext обнаруживают и  вызывать компоненты ApplicationContextAware, а также компоненты ResourceLoaderAware, ApplicationEventPublisherAware и MessageSourceAware.

В сценарии реального времени разница между контейнером Spring IOC Core (BeanFactory) и контейнером Advanced J2EE (ApplicationContext) заключается в следующем.

<Ол>
  • BeanFactory будет создавать объекты для bean-компонентов (то есть для классов POJO), упомянутых в файле spring.xml (<bean></bean>), только когда вы вызываете метод .getBean (), но ApplicationContext создает объекты для все компоненты (<=>, если его область явно не указана как " Prototype "), сконфигурированные в spring.xml при загрузке самого файла spring.xml.

  • BeanFactory: (Ленивый контейнер, потому что он создает объекты для bean-компонентов только при явном вызове из пользовательского / основного класса)

    /*
     * Using core Container - Lazy container - Because it creates the bean objects On-Demand
     */
    //creating a resource
    Resource r = (Resource) new ClassPathResource("com.spring.resources/spring.xml");
    //creating BeanFactory 
    BeanFactory factory=new XmlBeanFactory(r);
    
    //Getting the bean for the POJO class "HelloWorld.java"
    HelloWorld worldObj1 = (HelloWorld) factory.getBean("test");
    

    ApplicationContext: (готовый контейнер из-за создания объектов всех одноэлементных компонентов при загрузке самого файла spring.xml)

    ApplicationContext context = new ClassPathXmlApplicationContext("com/ioc/constructorDI/resources/spring.xml");
    
  • Технически рекомендуется использовать ApplicationContext, поскольку в приложениях реального времени объекты bean-объектов будут создаваться во время запуска приложения на самом сервере. Это сокращает время ответа на запрос пользователя, поскольку объекты уже доступны для ответа.

  • Я думаю, что стоит упомянуть, что начиная с Spring 3, если вы хотите создать фабрику, вы также можете использовать @configuration в сочетании с надлежащей @scope

    @Configuration
    public class MyFactory {
    
        @Bean
        @Scope("prototype")
        public MyClass create() {
            return new MyClass();
        }
    }
    

    Ваша фабрика должна быть видима контейнером Spring с помощью @ComponentScan аннотация или конфигурация xml

    Статья об объектах Spring Bean с сайта baeldung

    действительно используйте BeanFactory для не-веб-приложений, потому что он поддерживает только bean-области Singleton и Prototype.

    Контейнер ApplicationContext поддерживает все bean-области, поэтому его следует использовать для веб-приложений.

    В итоге:

    ApplicationContext включает в себя все функции BeanFactory. Обычно рекомендуется использовать первый.

    Есть некоторые ограниченные ситуации, например, в мобильном приложении, где потребление памяти может быть критическим.

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

    Подробнее читайте в моем блоге:

    Разница между BeanFactory и ApplicationContext весной & # 8211 ; Ява весенний блог с основами

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top