我是Spring Framework的新手,我一直在玩它并将一些示例应用程序放在一起,以便评估Spring MVC以用于即将到来的公司项目。到目前为止,我非常喜欢我在Spring MVC中看到的内容,看起来非常容易使用,并鼓励您编写非常适合单元测试的类。
就像练习一样,我正在为我的一个示例/测试项目编写一个主要方法。我不清楚的一件事是BeanFactory
和ApplicationContext
之间的确切差异 - 适合在哪些情况下使用?
我理解ApplicationContext
扩展BeanFactory
,但如果我只是编写一个简单的主要方法,我是否需要ApplicationContext
提供的额外功能?而且ApplicationContext
确实提供了什么样的额外功能?
除了回答“我应该在main()方法中使用哪个”之外,对于在这种情况下我应该使用哪种实现,是否有任何标准或指南?我的main()方法应该编写为依赖于bean /应用程序配置为XML格式 - 这是一个安全的假设,还是我将用户锁定为特定的东西?
这个答案是否会在网络环境中发生变化 - 如果我的任何课程需要了解Spring,他们是否更有可能需要ApplicationContext
?
感谢您的帮助。我知道很多这些问题可能在参考手册中得到了解答,但是我很难找到这两个界面的明确细分以及每个界面的优点/缺点而不通过精细梳齿阅读手册。
答案 0 :(得分:198)
春季文档非常棒:3.8.1. BeanFactory or ApplicationContext?。 他们有一个比较表,我将发布一个片段:
Bean Factory
申请背景
因此,如果您需要在应用程序上下文方面提供的任何要点,则应使用ApplicationContext。
答案 1 :(得分:45)
对我而言,选择BeanFactory
超过ApplicationContext
的主要区别似乎是ApplicationContext
将预先实例化所有bean。来自the Spring docs:
当实际创建bean时,Spring会尽可能晚地设置属性并解析依赖项。这意味着,如果在创建该对象或其某个依赖项时出现问题,则在请求对象时,正确加载的Spring容器可以在以后生成异常。例如,bean因缺少属性或无效属性而抛出异常。这可能会延迟一些配置问题的可见性,这就是默认情况下ApplicationContext实现预先实例化单例bean的原因。以实际需要之前创建这些bean的一些前期时间和内存为代价,您会在创建ApplicationContext时发现配置问题,而不是以后。您仍然可以覆盖此默认行为,以便单例bean可以进行惰性初始化,而不是预先实例化。
鉴于此,我最初选择BeanFactory
用于集成/性能测试,因为我不想加载整个应用程序来测试隔离的bean。但是 - 如果我错了,有人会纠正我 - BeanFactory
不支持classpath
XML配置。所以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);
}
}
}
答案 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 |
+---------------------------------------+-----------------+--------------------------------+
FileSystemXmlApplicationContext
豆子通过完整路径加载。ClassPathXmlApplicationContext
通过CLASSPATH XMLWebApplicationContext
和AnnotationConfigWebApplicationContext
bean通过Web应用程序上下文加载。AnnotationConfigApplicationContext
从基于Annotation的配置加载Spring bean。 示例:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
ApplicationContext
是由ContextLoaderListener
中定义的ContextLoaderServlet
或web.xml
以及ContextLoaderPlugin
中定义的struts-config.xml
初始化的容器。 注意:XmlBeanFactory
从Spring 3.1开始为deprecated,支持DefaultListableBeanFactory
和XmlBeanDefinitionReader
。
答案 3 :(得分:29)
要添加到Miguel Ping所回答的内容,这里的another section from the documentation也可以回答这个问题:
简短版本:使用ApplicationContext,除非您有充分的理由不这样做。对于那些正在寻找上述建议的“但为什么”更深入的人,请继续阅读。
(为未来可能会阅读此问题的春季新手发布此内容)
答案 4 :(得分:17)
ApplicationContext
比BeanFactory
在新的Spring版本中,BeanFactory
已替换为ApplicationContext
。但对于向后兼容性仍然存在BeanFactory
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);
<强>差分强>
BeanFactory 在调用 getBean()方法时实例化bean,而ApplicationContext在启动容器时实例化Singleton bean,它不等待getBean()被称为。
BeanFactory 不支持国际化,但 ApplicationContext 为其提供支持。
BeanFactory 与 ApplicationContext 之间的另一个区别是能够将事件发布到注册为侦听器的bean。
BeanFactory 界面的一个流行实现是 XMLBeanFactory ,而 ApplicationContext 界面的一个流行实现是的ClassPathXmlApplicationContext 强>
如果您使用自动布线并使用 BeanFactory ,则需要使用API注册 AutoWiredBeanPostProcessor ,如果您使用的是,则可以使用XML进行配置ApplicationContext的即可。总结 BeanFactory 可用于测试和非生产用途,但 ApplicationContext 是功能更丰富的容器实现,应该优于 BeanFactory
BeanFactory 默认支持延迟加载, ApplicationContext 默认支持积极加载。< / p>
答案 9 :(得分:5)
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");
答案 10 :(得分:4)
Feature Matrix of Bean Factory vs Application Context sourced from spring docs
Screenshot of features of BeanFacotry and ApplicationContext
答案 11 :(得分:3)
基本上我们可以用两种方式创建spring容器对象
两者都是接口
使用实现类,我们可以为spring容器创建对象
解决差异
BeanFactory
不支持基于注释的依赖注入。
不支持I18N
默认情况下,它支持延迟加载
它不允许配置多个配置文件。
ex:BeanFactory context = new XmlBeanFactory(new Resource(&#34; applicationContext.xml&#34;));
的ApplicationContext
支持基于注释的依赖注入.- @ Allowired,@ PreDestroy
支持I18N
默认支持Aggresive loading。
允许配置多个配置文件。
例如:
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)之间的区别如下。
只有在调用.getBean()方法时,BeanFactory才会为spring.xml文件(<bean></bean>
)中提到的bean(即POJO类)创建对象,但ApplicationContext会创建所有bean的对象(<bean></bean>
如果在加载spring.xml文件本身时未在spring.xml中明确提及其范围为&#34; Prototype&#34;)。
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");
从技术上讲,建议使用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配置
答案 17 :(得分:0)
将BeanFactory用于非Web应用程序,因为它仅支持Singleton和Prototype bean范围。
虽然ApplicationContext容器支持所有bean范围,因此您应该将它用于Web应用程序。
答案 18 :(得分:0)
总结:
ApplicationContext 包含BeanFactory的所有功能。 通常建议使用前者。
在某些情况下(例如在移动应用程序中),内存消耗可能至关重要。
在那种情况下,使用轻量级的 BeanFactory 是合理的。但是,在大多数企业应用程序中,您将要使用 ApplicationContext 。
有关更多信息,请参阅我的博客文章:
答案 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() 方法之前。 >