BeanFactory与ApplicationContext

mat*_*t b 221 spring managed-bean applicationcontext

我是Spring Framework的新手,我一直在玩它并将一些示例应用程序放在一起,以便评估Spring MVC以用于即将到来的公司项目.到目前为止,我非常喜欢我在Spring MVC中看到的内容,看起来非常容易使用,并鼓励您编写非常适合单元测试的类.

就像练习一样,我正在为我的一个示例/测试项目编写一个主要方法.我不清楚的一件事是BeanFactory和之间的确切差异ApplicationContext- 适合在哪些条件下使用?

我理解ApplicationContext扩展BeanFactory,但如果我只是编写一个简单的主方法,我是否需要ApplicationContext提供额外的功能?究竟是什么类型的额外功能ApplicationContext提供了?

除了回答"我应该在main()方法中使用哪个"之外,对于在这种情况下我应该使用哪种实现,是否有任何标准或指南?我的main()方法是否应该依赖于bean /应用程序配置以XML格式编写 - 这是一个安全的假设,还是我将用户锁定为特定的东西?

这个答案是否会在网络环境中发生变化 - 如果我的任何课程需要了解Spring,他们是否更有可能需要ApplicationContext

谢谢你的帮助.我知道很多这些问题可能在参考手册中得到了解答,但是我很难找到这两个界面的明确细分以及每个界面的优点/缺点而不通过精细梳齿阅读手册.

Mig*_*ing 202

春季文档很棒:3.8.1.BeanFactory或ApplicationContext?.他们有一个比较表,我将发布一个片段:

豆厂

  • Bean实例化/布线

应用背景

  • Bean实例化/布线
  • 自动BeanPostProcessor注册
  • 自动BeanFactoryPostProcessor注册
  • 方便的MessageSource访问(适用于i18n)
  • ApplicationEvent出版物

因此,如果您需要在应用程序上下文方面提供的任何要点,则应使用ApplicationContext.

  • BeanFactory是轻量级的,但是如果你要使用Spring"for real",那么你也可以使用ApplicationContext:如果你不使用它的花哨功能,那么所涉及的开销很小,但它们仍然可用如果/当你使用它们时. (3认同)
  • 链接 Spring 文档中的一个重要说明:“Spring 2.0 及更高版本大量使用 BeanPostProcessor 扩展点(以实现代理等),如果您只使用普通的 BeanFactory,那么大量支持,例如事务并且 AOP 不会生效(至少在没有你的一些额外步骤的情况下不会生效)。” (3认同)
  • 当你说"自动BeanPostPorcessor regisgration"时,它是什么意思?这是否意味着类不必实现该接口? (2认同)
  • ApplicationContext支持针对BeanFactory的AOP. (2认同)

Lyl*_*yle 47

对我来说,最主要的区别,选择BeanFactoryApplicationContext似乎是ApplicationContext将预先初始化所有的豆类.从春天文档:

当实际创建bean时,Spring会尽可能晚地设置属性并解析依赖关系.这意味着,如果在创建该对象或其某个依赖项时出现问题,则在请求对象时,正确加载的Spring容器可以在以后生成异常.例如,bean因缺少属性或无效属性而抛出异常.这可能会延迟一些配置问题的可见性,这就是默认情况下ApplicationContext实现预先实例化单例bean的原因.以实际需要之前创建这些bean的一些前期时间和内存为代价,您会在创建ApplicationContext时发现配置问题,而不是更晚.您仍然可以覆盖此默认行为,以便单例bean将延迟初始化,而不是预先实例化.

鉴于此,我最初选择BeanFactory用于集成/性能测试,因为我不想加载整个应用程序来测试隔离的bean.但是 - 如果我错了,有人会纠正我 - BeanFactory不支持classpathXML配置.所以BeanFactory,ApplicationContext每个都提供了我想要的关键功能,但两者都没有.

我可以说,文档中关于覆盖默认实例化行为的注释发生在配置中,并且它是每个bean,所以我不能只在XML文件中设置"lazy-init"属性或者我是坚持维护它的一个版本用于测试,一个用于部署.

我最终做的是扩展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);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 我认为,如果您的单元测试加载了完整的Spring上下文,它们不是"单元测试",而是集成测试. (2认同)
  • `BeanFactory 不支持类路径 XML 配置。` 我认为它支持:http://stackoverflow.com/questions/5231371/springs-xmlbeanfactory-is-deprecated (2认同)

Pre*_*raj 44

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                            |
+---------------------------------------+-----------------+--------------------------------+
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • FileSystemXmlApplicationContext 豆通过完整的路径加载.
  • ClassPathXmlApplicationContext 通过CLASSPATH加载的Bean
  • XMLWebApplicationContextAnnotationConfigWebApplicationContextbean通过Web应用程序上下文加载.
  • AnnotationConfigApplicationContext 从基于Annotation的配置加载Spring bean.

例:

  ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
Run Code Online (Sandbox Code Playgroud)
  • ApplicationContext是由初始化的容器ContextLoaderListenerContextLoaderServlet以限定的web.xmlContextLoaderPlugin所限定struts-config.xml.

:XmlBeanFactory弃用赞成作为春季3.1 DefaultListableBeanFactoryXmlBeanDefinitionReader.

  • 它的 AnnotationConfigApplicationContext 不是 -AnnotationConfigWebApplicationContext- 在图中 ClassPathXmlApplicationContext 下方 (2认同)

mat*_*t b 29

要添加到Miguel Ping所回答的内容,这里是文档的另一部分,它也回答了这个问题:

简短版本:使用ApplicationContext,除非你有充分理由不这样做.对于那些正在寻找上述建议的"但为什么"更深入的人,请继续阅读.

(发布这个适用于未来可能会阅读此问题的Spring新手)


小智 18

  1. ApplicationContext 是比较喜欢的方式 BeanFactory

  2. 在新的Spring版本BeanFactory中替换为ApplicationContext.但仍然BeanFactory存在向后兼容性

  3. ApplicationContext extends BeanFactory 并具有以下好处
    • 它支持短信的国际化
    • 它支持向注册的听众发布事件
    • 访问URL和文件等资源


Cho*_*hos 12

我认为最好始终使用ApplicationContext,除非你像其他人已经说过的那样处于移动环境中.ApplicationContext具有更多功能,您肯定希望使用PostProcessors,如RequiredAnnotationBeanPostProcessor,AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor,它们将帮助您简化Spring配置文件,并且您可以在bean中使用@ Required,@ PostConstruct,@ Resource等注释. .

即使您没有使用ApplicationContext提供的所有内容,最好还是使用它,然后如果您决定使用某些资源(如消息或后处理器)或其他模式来添加事务性建议等等,已经有一个ApplicationContext,不需要更改任何代码.

如果您正在编写独立应用程序,请使用ClassPathXmlApplicationContext在main方法中加载ApplicationContext,并获取主bean并调用其run()(或任何方法)来启动您的应用程序.如果您正在编写Web应用程序,请使用web.xml中的ContextLoaderListener,以便它创建ApplicationContext,稍后您可以从ServletContext获取它,无论您使用的是JSP,JSF,JSTL,struts,Tapestry等. .

另外,记住你可以使用多个Spring配置文件,你可以通过列出构造函数中的所有文件来创建ApplicationContext(或者在ContextLoaderListener的context-param中列出它们),或者你可以只加载一个主配置文件进口报表.您可以使用<import resource ="otherfile.xml"/>将Spring配置文件导入另一个Spring配置文件,这在以main方法编程创建ApplicationContext并仅加载一个Spring配置文件时非常有用.


vin*_*nod 10

ApplicationContext: 它加载在spring配置文件中配置的spring bean,并管理spring bean的生命周期和WHEN CONTAINER STARTS.It不会等到调用getBean("springbeanref").

BeanFactory 它加载在spring配置文件中配置的spring bean,当我们调用getBean("springbeanref")时管理spring bean的生命周期.所以当我们在spring bean生命周期开始时调用getBean("springbeanref")时.


Rya*_*mes 6

在大多数情况下,ApplicationContext是首选,除非您需要节省资源,例如在移动应用程序上.

我不确定依赖于XML格式,但我非常确定ApplicationContext的最常见实现是XML,例如ClassPathXmlApplicationContext,XmlWebApplicationContext和FileSystemXmlApplicationContext.这是我用过的唯一三个.

如果您正在开发一个Web应用程序,可以说您需要使用XmlWebApplicationContext.

如果你希望你的bean知道Spring,你可以让它们为它实现BeanFactoryAware和/或ApplicationContextAware,这样你就可以使用BeanFactory或ApplicationContext并选择要实现的接口.


Luc*_*cky 5

来自 spring 文档的 Bean Factory 与应用程序上下文特征矩阵

在此处输入图片说明

BeanFacotry 和 ApplicationContext 的特性截图


Div*_*iya 5

BeanFactoryApplicationContext都是从spring IOC容器中获取bean的方法,但仍有一些区别.

BeanFactory是实例化,配置和管理许多bean的实际容器.这些bean通常彼此协作,因此它们之间具有依赖关系.这些依赖关系反映在BeanFactory使用的配置数据中.

BeanFactoryApplicationContext都是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);
Run Code Online (Sandbox Code Playgroud)

区别

  1. BeanFactory在调用getBean()方法时实例化bean,而ApplicationContext在启动容器时实例化Singleton bean,它不等待调用getBean().

  2. BeanFactory不支持国际化,但ApplicationContext提供了对它的支持.

  3. BeanFactoryApplicationContext之间的另一个区别是能够将事件发布到注册为侦听器的bean.

  4. 其中一个流行的实现的Bean工厂接口是XmlBeanFactory中,而流行的实现的一个ApplicationContext的接口是ClassPathXmlApplicationContext的.

  5. 如果使用自动布线并使用BeanFactory,则需要使用API 注册AutoWiredBeanPostProcessor,如果使用ApplicationContext,则可以使用XML进行配置 .总之,BeanFactory可用于测试和非生产使用,但ApplicationContext是功能更丰富的容器实现,应该优于BeanFactory

  6. 默认情况下,BeanFactory支持Lazy加载,默认情况下ApplicationContext支持Aggresive加载.


小智 5

基本上我们可以通过两种方式创建spring容器对象

  1. 使用 BeanFactory。
  2. 使用应用程序上下文。

两者都是接口,

使用实现类,我们可以为 spring 容器创建对象

来到差异

豆工厂:

  1. 不支持基于注解的依赖注入。

  2. 不支持 I18N。

  3. 默认情况下它支持延迟加载。

  4. 它不允许配置到多个配置文件。

例如:BeanFactory context=new XmlBeanFactory(new Resource("applicationContext.xml"));

应用上下文

  1. 支持基于注解的依赖注入。-@Autowired, @PreDestroy

  2. 支持 I18N

  3. 它的默认支持积极加载。

  4. 它允许配置多个配置文件。

例如:
ApplicationContext context=new ClasspathXmlApplicationContext("applicationContext.xml");


Ram*_*pta 5

BeanFactoryApplicationContext之间的区别如下:

  1. BeanFactory使用延迟初始化, ApplicationContext使用急切初始化.对于BeanFactory,在调用getBeans()方法时会创建bean,但是在创建ApplicationContext对象时,在ApplicationContext的情况下会创建bean.
  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");