Spring BeanFactory vs ApplicationContext

Spring BeanFactory vs ApplicationContext,spring,managed-bean,applicationcontext,Spring,Managed Bean,Applicationcontext,我对Spring框架还很陌生,我一直在使用它,并将一些示例应用程序放在一起,以便评估Spring MVC,以便在即将到来的公司项目中使用。到目前为止,我非常喜欢我在SpringMVC中看到的东西,似乎非常易于使用,并鼓励您编写非常单元测试友好的类 作为练习,我正在为我的一个示例/测试项目编写一个主要方法。我不清楚的一点是BeanFactory和ApplicationContext之间的确切区别-在哪些条件下使用哪个合适 我知道ApplicationContext扩展了BeanFactory,但如

我对Spring框架还很陌生,我一直在使用它,并将一些示例应用程序放在一起,以便评估Spring MVC,以便在即将到来的公司项目中使用。到目前为止,我非常喜欢我在SpringMVC中看到的东西,似乎非常易于使用,并鼓励您编写非常单元测试友好的类

作为练习,我正在为我的一个示例/测试项目编写一个主要方法。我不清楚的一点是
BeanFactory
ApplicationContext
之间的确切区别-在哪些条件下使用哪个合适

我知道
ApplicationContext
扩展了
BeanFactory
,但如果我只是在编写一个简单的main方法,我是否需要
ApplicationContext
提供的额外功能?而
ApplicationContext
到底提供了什么样的额外功能呢

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

如果我的任何类需要了解Spring,它们是否更可能需要
ApplicationContext


谢谢你的帮助。我知道这些问题中有很多可能在参考手册中得到了回答,但如果不仔细阅读手册,我很难找到这两个接口的清晰分类以及每个接口的优缺点。

spring文档在这方面做得很好:。 他们有一个带有比较的表,我将发布一个片段:

豆工厂

  • Bean实例化/连接
应用程序上下文

  • Bean实例化/连接
  • 自动BeanPostProcessor注册
  • 自动BeanFactory后处理器注册
  • 方便的消息源访问(适用于i18n)
  • ApplicationEvent出版物

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

要补充Miguel Ping所回答的内容,这里也回答了这个问题:

简短版本:使用ApplicationContext,除非你有很好的理由不这样做。对于那些想对上述建议的“但为什么”有更深入了解的人,请继续阅读


(为可能阅读此问题的任何未来Spring新手发布此帖子)

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

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

如果您正在开发web应用程序,可以肯定地说您需要使用XmlWebApplicationContext


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

我认为最好始终使用ApplicationContext,除非你像别人说的那样身处移动环境。ApplicationContext具有更多功能,您肯定希望使用后处理器,如RequiredAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor,这将帮助您简化Spring配置文件,并且您可以使用诸如@Required、@PostConstruct、@Resource、,等在你的豆子里

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

如果您正在编写独立应用程序,请使用ClassPathXmlApplicationContext在主方法中加载ApplicationContext,然后获取主bean并调用其run()(或任何方法)来启动应用程序。如果您正在编写一个web应用程序,请使用web.xml中的ContextLoaderListener,这样它就可以创建ApplicationContext,以后您就可以从ServletContext中获取它,而不管您使用的是JSP、JSF、JSTL、struts、Tapestry等

另外,请记住,您可以使用多个Spring配置文件,您可以通过在构造函数中列出所有文件(或在ContextLoaderListener的上下文参数中列出这些文件)来创建ApplicationContext,也可以只加载包含导入语句的主配置文件。您可以使用将一个Spring配置文件导入到另一个Spring配置文件中,这在以编程方式在main方法中创建ApplicationContext并仅加载一个Spring配置文件时非常有用

  • ApplicationContext
    BeanFactory

  • 在新的Spring版本中,
    BeanFactory
    ApplicationContext
    取代。但是仍然
    BeanFactory
    是为了向后兼容而存在的

  • ApplicationContext扩展了BeanFactory
    ,并具有以下优点
    • 它支持文本消息的国际化
    • 它支持向注册的侦听器发布事件
    • 对URL和文件等资源的访问

  • 对我来说,选择
    BeanFactory
    而不是
    ApplicationContext
    的主要区别似乎是
    ApplicationContext
    w
    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);
            }
        }
    
    }
    
    ClassPathResource resource = new ClassPathResource("appConfig.xml");
    XmlBeanFactory factory = new XmlBeanFactory(resource);
    
    +---------------------------------------+-----------------+--------------------------------+
    |                                       | 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                            |
    +---------------------------------------+-----------------+--------------------------------+
    
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
    
    /*
     * 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 context = new ClassPathXmlApplicationContext("com/ioc/constructorDI/resources/spring.xml");
    
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
    
    ApplicationContext context = new ClassPathXmlApplicationContext{"spring_dao.xml","spring_service.xml};
    
    BeanFactory beanfactory = new XMLBeanFactory(new FileSystemResource("spring.xml"));
     Triangle triangle =(Triangle)beanFactory.getBean("triangle");
    
    ApplicationContext context = new ClassPathXMLApplicationContext("spring.xml")
    Triangle triangle =(Triangle)context.getBean("triangle");
    
    @Configuration
    public class MyFactory {
    
        @Bean
        @Scope("prototype")
        public MyClass create() {
            return new MyClass();
        }
    }