BeanFactory与ApplicationContext

时间:2008-10-28 13:50:19

标签: spring managed-bean applicationcontext

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

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

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

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

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

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

21 个答案:

答案 0 :(得分:198)

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

Bean Factory

  • Bean实例化/接线

申请背景

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

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

答案 1 :(得分:45)

对我而言,选择BeanFactory超过ApplicationContext的主要区别似乎是ApplicationContext将预先实例化所有bean。来自the Spring docs

  

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

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

我可以说,关于覆盖默认实例化行为的文档中的注释发生在配置中,并且它是每个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);
        }
    }

}

答案 2 :(得分:35)

  

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
  • 加载的Bean
  • XMLWebApplicationContextAnnotationConfigWebApplicationContext bean通过Web应用程序上下文加载。
  • AnnotationConfigApplicationContext从基于Annotation的配置加载Spring bean。

示例:

  ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
  • ApplicationContext是由ContextLoaderListener中定义的ContextLoaderServletweb.xml以及ContextLoaderPlugin中定义的struts-config.xml初始化的容器。

注意XmlBeanFactory从Spring 3.1开始为deprecated,支持DefaultListableBeanFactoryXmlBeanDefinitionReader

答案 3 :(得分:29)

要添加到Miguel Ping所回答的内容,这里的another section from the documentation也可以回答这个问题:

  

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

(为未来可能会阅读此问题的春季新手发布此内容)

答案 4 :(得分:17)

  1. ApplicationContextBeanFactory

  2. 更受欢迎
  3. 在新的Spring版本中,BeanFactory已替换为ApplicationContext。但对于向后兼容性仍然存在BeanFactory

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

答案 5 :(得分: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语句的文件。您可以使用< import resource =“otherfile.xml”/>将Spring配置文件导入另一个Spring配置文件中。当您在main方法中以编程方式创建ApplicationContext并仅加载一个Spring配置文件时,这非常有用。

答案 6 :(得分:10)

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

<强>的BeanFactory  它加载在spring配置文件中配置的spring bean,当我们调用 getBean(“springbeanref”)时管理spring bean的生命周期。所以当我们调用 getBean(“springbeanref”)时在春豆生命周期开始时。

答案 7 :(得分:6)

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

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

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

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

答案 8 :(得分:5)

BeanFactory ApplicationContext 都是从你的spring IOC 容器中获取bean的方法,但仍有一些区别。

BeanFactory 是实例化,配置和管理多个bean的实际容器。这些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 在调用 getBean()方法时实例化bean,而ApplicationContext在启动容器时实例化Singleton bean,它不等待getBean()被称为。

  2. BeanFactory 不支持国际化,但 ApplicationContext 为其提供支持。

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

  4. BeanFactory 界面的一个流行实现是 XMLBeanFactory ,而 ApplicationContext 界面的一个流行实现是的ClassPathXmlApplicationContext

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

  6. BeanFactory 默认支持延迟加载, ApplicationContext 默认支持积极加载。< / p>

答案 9 :(得分:5)

BeanFactory ApplicationContext 的区别如下:

  1. BeanFactory使用延迟初始化,但 ApplicationContext使用急切初始化。对于BeanFactory,在调用getBeans()方法时会创建bean,但是在创建ApplicationContext对象时,在ApplicationContext的情况下会创建bean。
  2. BeanFactory使用语法显式提供资源对象,但 ApplicationContext自己创建和管理资源对象。
  3. BeanFactory不支持国际化,但 ApplicationContext支持国际化。
  4. 不支持基于BeanFactory注释的依赖注入但ApplicationContext支持基于注释的依赖注入。
  5. 使用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");

答案 10 :(得分:4)

Feature Matrix of Bean Factory vs Application Context sourced from spring docs

enter image description here

Screenshot of features of BeanFacotry and ApplicationContext

答案 11 :(得分:3)

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

  1. 使用BeatFactory
  2. 使用ApplicationContext
  3. 两者都是接口

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

    解决差异

    BeanFactory

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

    2. 不支持I18N

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

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

    5. ex:BeanFactory context = new XmlBeanFactory(new Resource(&#34; applicationContext.xml&#34;));

      的ApplicationContext

      1. 支持基于注释的依赖注入.- @ Allowired,@ PreDestroy

      2. 支持I18N

      3. 默认支持Aggresive loading。

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

      5. 例如:
        ApplicationContext context = new ClasspathXmlApplicationContext(&#34; applicationContext.xml&#34;);

答案 12 :(得分:3)

一个。 bean工厂和应用程序上下文之间的一个区别是,当您调用getBean()方法时,前者仅实例化bean,而ApplicationContext在启动容器时实例化Singleton bean,它不等待调用getBean。

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

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

您可以根据项目要求使用一个或多个xml文件。因为我在这里使用两个xml文件,即一个用于dao类的服务类的配置细节。这里ClassPathXmlApplicationContext是ApplicationContext的子代。

℃。 BeanFactory Container是基本容器,它只能创建对象并注入依赖项。但我们不能附加其他服务,如安全性,事务,消息传递等,以提供我们使用ApplicationContext Container的所有服务。

d。 BeanFactory不支持国际化,即i18n,但ApplicationContext提供了对它的支持。

即BeanFactory Container不支持AutoScanning(基于支持注释的依赖注入)的功能,但ApplicationContext Container支持。

F。 Beanfactory Container在请求时间之前不会创建bean对象。这意味着Beanfactory Container懒洋洋地加载bean。 ApplicationContext Container仅在加载时创建Singleton bean的对象。这意味着有早期装载。

克。 Beanfactory Container仅支持bean的两个范围(singleton&amp; prototype)。但ApplicationContext Container支持所有bean范围。

答案 13 :(得分:1)

ApplicationContext是BeanFactory的一个大兄弟,这将是BeanFactory提供的所有功能以及许多其他功能。

除了标准的org.springframework.beans.factory.BeanFactory生命周期功能外,ApplicationContext实现还检测和  调用ApplicationContextAware bean以及ResourceLoaderAware,ApplicationEventPublisherAware和MessageSourceAware bean。

答案 14 :(得分:1)

在实时场景中,Spring IOC Core容器(BeanFactory)和Advanced J2EE容器(ApplicationContext)之间的区别如下。

  1. 只有在调用.getBean()方法时,BeanFactory才会为spring.xml文件(<bean></bean>)中提到的bean(即POJO类)创建对象,但ApplicationContext会创建所有bean的对象(<bean></bean>如果在加载spring.xml文件本身时未在spring.xml中明确提及其范围为&#34; Prototype&#34;)。

  2. 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文件时创建了所有单例bean的对象,因此是Eager容器)

    ApplicationContext context = new ClassPathXmlApplicationContext("com/ioc/constructorDI/resources/spring.xml");
    
  3. 从技术上讲,建议使用ApplicationContext,因为在实时应用程序中,将在服务器本身启动应用程序时创建bean对象。这减少了用户请求的响应时间,因为对象已经可以响应。

答案 15 :(得分:1)

请参阅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,除了一些情况,例如在Applet中,内存消耗可能很关键,而一些额外的千字节可能会有所不同。但是,对于大多数典型的企业应用程序和系统,ApplicationContext是您要使用的。 Spring 2.0及更高版本大量使用BeanPostProcessor扩展点(以实现代理等)。如果你只使用一个简单的BeanFactory,那么交易和AOP等相当数量的支持将不会生效,至少在没有你做一些额外步骤的情况下也是如此。这种情况可能会令人困惑,因为配置实际上没有任何问题。

答案 16 :(得分:0)

我认为值得一提的是,从Spring 3开始,如果你想创建一个工厂,你也可以使用@configuration注释结合正确的@scope

@Configuration
public class MyFactory {

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

Spring容器应使用@ComponentScan注释或xml配置

显示您的工厂

Spring bean scopes article from baeldung site

答案 17 :(得分:0)

将BeanFactory用于非Web应用程序,因为它仅支持Singleton和Prototype bean范围。

虽然ApplicationContext容器支持所有bean范围,因此您应该将它用于Web应用程序。

答案 18 :(得分:0)

总结:

ApplicationContext 包含BeanFactory的所有功能。 通常建议使用前者。

在某些情况下(例如在移动应用程序中),内存消耗可能至关重要。

在那种情况下,使用轻量级的 BeanFactory 是合理的。但是,在大多数企业应用程序中,您将要使用 ApplicationContext

有关更多信息,请参阅我的博客文章:

Difference between BeanFactory and ApplicationContext in Spring – The java spring blog from the basics

答案 19 :(得分:0)

我需要解释BeanFactory和ApplicationContext。

BeanFactory: BeanFactory是用于访问SpringBean Container的根接口。有bean容器的基本客户端视图。 该接口由保存多个bean定义的对象类实现,并且每个对象均由String名称唯一标识
根据Bean的定义,工厂将返回实例,该实例可以是所包含对象的实例,也可以是单个共享实例。返回哪种类型的实例取决于bean工厂的配置。
通常,Bean工厂将加载所有的所有bean定义,这些定义存储在XML ...等配置源中。

BeanFactory是最简单的容器,为依赖注入提供基本支持

应用上下文 应用程序上下文是spring应用程序中的中央接口,用于向应用程序提供配置信息。它实现了Bean Factory接口。

应用程序上下文是一个高级容器,它增加了企业特定功能的高级级别,例如从属性文件中解析文本消息的能力。...等

ApplicationContext提供:

用于访问应用程序组件的Bean工厂方法。继承自ListableBeanFactory。 以通用方式加载文件资源的能力。继承自ResourceLoader接口。 将事件发布给注册的侦听器的能力。继承自ApplicationEventPublisher接口。 解决消息的能力,支持国际化。继承自MessageSource接口。 从父上下文继承。在后代上下文中的定义将始终优先。例如,这意味着整个Web应用程序都可以使用单个父上下文,而每个servlet都有其自己的子上下文,该子上下文独立于任何其他servlet的子上下文。 除了标准的BeanFactory生命周期功能之外,ApplicationContext实现还检测并调用ApplicationContextAware Bean以及ResourceLoaderAware,ApplicationEventPublisherAware和MessageSourceAware Bean。

答案 20 :(得分:0)

BeanFactory 表示在运行时调用 getBean() 方法后延迟实例化 bean 对象的 spring 容器。

ApplicationContext 表示 Spring 框架,它在部署期间急切实例化 bean 对象,而无需或在运行时调用 getBean() 方法之前。 >