spring BeanFactory 与 ApplicationContext
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/243385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
BeanFactory vs ApplicationContext
提问by matt b
I'm pretty new to the Spring Framework, I've been playing around with it and putting a few samples apps together for the purposes of evaluating Spring MVC for use in an upcoming company project. So far I really like what I see in Spring MVC, seems very easy to use and encourages you to write classes that are very unit test-friendly.
我对 Spring Framework 还很陌生,我一直在玩弄它并将一些示例应用程序放在一起,以评估 Spring MVC 以便在即将到来的公司项目中使用。到目前为止,我真的很喜欢我在 Spring MVC 中看到的东西,它看起来非常易于使用,并鼓励您编写对单元测试非常友好的类。
Just as an exercise, I'm writing a main method for one of my sample/test projects. One thing I'm unclear about is the exact differences between BeanFactoryand ApplicationContext- which is appropriate to use in which conditions?
作为练习,我正在为我的一个示例/测试项目编写一个主要方法。我不清楚的一件事是BeanFactory和之间的确切区别ApplicationContext- 适合在哪些条件下使用?
I understand that ApplicationContextextends BeanFactory, but if I'm just writing a simple main method, do I need the extra functionality that ApplicationContextprovides? And just exactly what kind of extra functionality does ApplicationContextprovide?
我知道ApplicationContextextends BeanFactory,但如果我只是编写一个简单的 main 方法,我是否需要ApplicationContext提供的额外功能?究竟提供了什么样的额外功能ApplicationContext?
In addition to answering "which should I use in a main() method", are there any standards or guidelines as far as which implementation I should use in such a scenario? Should my main() method be written to depend on the bean/application configuration to be in XML format - is that a safe assumption, or am I locking the user into something specific?
除了回答“我应该在 main() 方法中使用哪个”之外,是否有任何标准或指南来说明在这种情况下我应该使用哪种实现?我的 main() 方法是否应该被编写为依赖于 XML 格式的 bean/应用程序配置 - 这是一个安全的假设,还是我将用户锁定到特定的东西?
And does this answer change in a web environment - if any of my classes needed to be aware of Spring, are they more likely to need ApplicationContext?
这个答案在 Web 环境中是否会发生变化 - 如果我的任何类需要了解 Spring,它们是否更有可能需要ApplicationContext?
Thanks for any help. I know a lot of these questions are probably answered in the reference manual, but I'm having a hard time finding a clear breakdown of these two interfaces and the pros/cons of each without reading thru the manual with a fine-tooth comb.
谢谢你的帮助。我知道很多这些问题可能在参考手册中得到了回答,但我很难找到这两个界面的明确分类以及每个界面的优缺点,而不是用细齿梳通读手册。
采纳答案by Miguel Ping
The spring docs are great on this: 3.8.1. BeanFactory or ApplicationContext?. They have a table with a comparison, I'll post a snippet:
spring 文档在这方面很棒:3.8.1。BeanFactory 还是 ApplicationContext?. 他们有一个比较表,我会发布一个片段:
Bean Factory
豆厂
- Bean instantiation/wiring
- Bean 实例化/接线
Application Context
应用上下文
- Bean instantiation/wiring
- Automatic BeanPostProcessor registration
- Automatic BeanFactoryPostProcessor registration
- Convenient MessageSource access (for i18n)
- ApplicationEvent publication
- Bean 实例化/接线
- 自动 BeanPostProcessor 注册
- 自动 BeanFactoryPostProcessor 注册
- 方便的 MessageSource 访问(适用于 i18n)
- 应用事件发布
So if you need any of the points presented on the Application Context side, you should use ApplicationContext.
因此,如果您需要应用程序上下文方面的任何要点,您应该使用 ApplicationContext。
回答by Premraj
Spring provides two kinds of IOC container, one is
XMLBeanFactoryand other isApplicationContext.
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 |
+---------------------------------------+-----------------+--------------------------------+
FileSystemXmlApplicationContextBeans loaded through the full path.ClassPathXmlApplicationContextBeans loaded through the CLASSPATHXMLWebApplicationContextandAnnotationConfigWebApplicationContextbeans loaded through the web application context.AnnotationConfigApplicationContextLoading Spring beans from Annotation based configuration.
FileSystemXmlApplicationContext通过完整路径加载的 Bean。ClassPathXmlApplicationContext通过 CLASSPATH 加载的 BeanXMLWebApplicationContext和AnnotationConfigWebApplicationContext通过 Web 应用程序上下文加载的 bean。AnnotationConfigApplicationContext从基于注释的配置加载 Spring bean。
example:
例子:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
ApplicationContextis the container initialized by aContextLoaderListenerorContextLoaderServletdefined in aweb.xmlandContextLoaderPlugindefined instruts-config.xml.
ApplicationContext是由 a 初始化ContextLoaderListener或ContextLoaderServlet在 a 中定义web.xml并ContextLoaderPlugin在 中定义的容器struts-config.xml。
Note: XmlBeanFactoryis deprecatedas of Spring 3.1 in favor of DefaultListableBeanFactoryand XmlBeanDefinitionReader.
注:XmlBeanFactory被弃用如春3.1赞成的DefaultListableBeanFactory和XmlBeanDefinitionReader。
回答by Lyle
To me, the primary difference to choose BeanFactoryover ApplicationContextseems to be that ApplicationContextwill pre-instantiate all of the beans. From the Springdocs:
对我来说,最主要的区别,选择BeanFactory了ApplicationContext似乎是ApplicationContext将预实例所有的豆类。从在春天文档:
Spring sets properties and resolves dependencies as late as possible, when the bean is actually created. This means that a Spring container which has loaded correctly can later generate an exception when you request an object if there is a problem creating that object or one of its dependencies. For example, the bean throws an exception as a result of a missing or invalid property. This potentially delayed visibility of some configuration issues is why ApplicationContext implementations by default pre-instantiate singleton beans. At the cost of some upfront time and memory to create these beans before they are actually needed, you discover configuration issues when the ApplicationContext is created, not later. You can still override this default behavior so that singleton beans will lazy-initialize, rather than be pre-instantiated.
Spring 在真正创建 bean 时尽可能晚地设置属性并解析依赖项。这意味着,如果创建该对象或其依赖项时出现问题,则已正确加载的 Spring 容器稍后可以在您请求对象时生成异常。例如,由于缺少或无效的属性,bean 会抛出异常。某些配置问题的这种潜在延迟可见性是 ApplicationContext 实现默认预实例化单例 bean 的原因。以在实际需要之前创建这些 bean 的一些前期时间和内存为代价,您会在创建 ApplicationContext 时发现配置问题,而不是稍后。您仍然可以覆盖此默认行为,以便单例 bean 延迟初始化,而不是预先实例化。
Given this, I initially chose BeanFactoryfor use in integration/performance tests since I didn't want to load the entire application for testing isolated beans. However -- and somebody correct me if I'm wrong -- BeanFactorydoesn't support classpathXML configuration. So BeanFactoryand ApplicationContexteach provide a crucial feature I wanted, but neither did both.
鉴于此,我最初选择BeanFactory用于集成/性能测试,因为我不想加载整个应用程序来测试隔离的 bean。但是——如果我错了,有人会纠正我——BeanFactory不支持classpathXML 配置。因此BeanFactory,ApplicationContext每个都提供了我想要的关键功能,但两者都没有。
Near as I can tell, the note in the documentation about overriding default instantiation behavior takes place in the configuration, and it's per-bean, so I can't just set the "lazy-init" attribute in the XML file or I'm stuck maintaining a version of it for test and one for deployment.
就我所知,文档中关于覆盖默认实例化行为的注释发生在配置中,它是针对每个 bean 的,所以我不能只在 XML 文件中设置“lazy-init”属性,或者我是坚持维护一个用于测试的版本和一个用于部署的版本。
What I ended up doing was extending ClassPathXmlApplicationContextto lazily load beans for use in tests like so:
我最终做的是扩展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);
}
}
}
回答by matt b
To add onto what Miguel Ping answered, here is another section from the documentationthat answers this as well:
要添加 Miguel Ping 的回答,这里是文档中的另一部分也回答了这个问题:
Short version: use an ApplicationContext unless you have a really good reason for not doing so. For those of you that are looking for slightly more depth as to the 'but why' of the above recommendation, keep reading.
简短版本:除非您有充分的理由不这样做,否则请使用 ApplicationContext。对于那些正在寻找关于上述建议的“但为什么”的更深入的人,请继续阅读。
(posting this for any future Spring novices who might read this question)
(为将来可能会阅读此问题的任何 Spring 新手发布此信息)
回答by srinivas reddy
ApplicationContextis more preferred way thanBeanFactoryIn new Spring versions
BeanFactoryis replaced withApplicationContext. But stillBeanFactoryexists for backward compatabilityApplicationContext extends BeanFactoryand has the following benefits- it supports internationalization for text messages
- it supports event publication to the registered listeners
- access to the resources such as URLs and files
ApplicationContext比BeanFactory在新的 Spring 版本
BeanFactory中替换为ApplicationContext. 但仍然BeanFactory存在向后兼容性ApplicationContext extends BeanFactory并有以下好处- 支持短信国际化
- 它支持事件发布到注册的监听器
- 访问资源,例如 URL 和文件
回答by vinod
ApplicationContext:It loads spring beans configured in spring configuration file,and manages the life cycle of the spring bean as and WHEN CONTAINER STARTS.It won't wait until getBean("springbeanref")is called.
ApplicationContext:加载spring配置文件中配置的spring bean,在container STARTS和WHEN CONTAINER STARTS时管理spring bean的生命周期,不会等到getBean("springbeanref")被调用。
BeanFactoryIt loads spring beans configured in spring configuration file,manages the life cycle of the spring bean when we call the getBean("springbeanref").So when we call the getBean("springbeanref")at the time of spring bean life cycle starts.
BeanFactory的IT负载春豆在Spring配置文件配置,管理的Spring bean的生命周期,当我们调用的getBean(“springbeanref”) 。所以当我们调用的getBean(“springbeanref”)在春豆的生命周期开始的时间.
回答by Chochos
I think it's better to always use ApplicationContext, unless you're in a mobile environment like someone else said already. ApplicationContext has more functionality and you definitely want to use the PostProcessors such as RequiredAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor and CommonAnnotationBeanPostProcessor, which will help you simplify your Spring configuration files, and you can use annotations such as @Required, @PostConstruct, @Resource, etc in your beans.
我认为最好始终使用 ApplicationContext,除非您像其他人所说的那样处于移动环境中。ApplicationContext 有更多的功能,你肯定想使用后处理器,如 RequiredAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor,这将帮助你简化你的 Spring 配置文件,你可以在你的 bean 中使用诸如 @Required、@PostConstruct、@Resource 等注解.
Even if you don't use all the stuff ApplicationContext offers, it's better to use it anyway, and then later if you decide to use some resource stuff such as messages or post processors, or the other schema to add transactional advices and such, you will already have an ApplicationContext and won't need to change any code.
即使你不使用 ApplicationContext 提供的所有东西,最好还是使用它,然后如果你决定使用一些资源东西,比如消息或后处理器,或者其他模式来添加事务建议等等,你已经有一个 ApplicationContext 并且不需要更改任何代码。
If you're writing a standalone app, load the ApplicationContext in your main method, using a ClassPathXmlApplicationContext, and get the main bean and invoke its run() (or whatever method) to start your app. If you're writing a web app, use the ContextLoaderListener in web.xml so that it creates the ApplicationContext and you can later get it from the ServletContext, regardless of whether you're using JSP, JSF, JSTL, struts, Tapestry, etc.
如果您正在编写一个独立的应用程序,请在您的主方法中加载 ApplicationContext,使用 ClassPathXmlApplicationContext,并获取主 bean 并调用其 run()(或任何方法)来启动您的应用程序。如果您正在编写 Web 应用程序,请使用 web.xml 中的 ContextLoaderListener 以便它创建 ApplicationContext 并且您以后可以从 ServletContext 获取它,无论您使用的是 JSP、JSF、JSTL、struts、Tapestry 等.
Also, remember you can use multiple Spring configuration files and you can either create the ApplicationContext by listing all the files in the constructor (or listing them in the context-param for the ContextLoaderListener), or you can just load a main config file which has import statements. You can import a Spring configuration file into another Spring configuration file by using <import resource="otherfile.xml" /> which is very useful when you programmatically create the ApplicationContext in the main method and load only one Spring config file.
另外,请记住,您可以使用多个 Spring 配置文件,您可以通过在构造函数中列出所有文件(或在 ContextLoaderListener 的上下文参数中列出它们)来创建 ApplicationContext,或者您可以只加载一个主配置文件,该文件具有导入语句。您可以使用 <import resource="otherfile.xml" /> 将一个 Spring 配置文件导入到另一个 Spring 配置文件中,这在您以编程方式在 main 方法中创建 ApplicationContext 并仅加载一个 Spring 配置文件时非常有用。
回答by Ryan Thames
For the most part, ApplicationContext is preferred unless you need to save resources, like on a mobile application.
大多数情况下,ApplicationContext 是首选,除非您需要节省资源,例如在移动应用程序上。
I'm not sure about depending on XML format, but I'm pretty sure the most common implementations of ApplicationContext are the XML ones such as ClassPathXmlApplicationContext, XmlWebApplicationContext, and FileSystemXmlApplicationContext. Those are the only three I've ever used.
我不确定是否依赖于 XML 格式,但我很确定 ApplicationContext 最常见的实现是 XML 实现,例如 ClassPathXmlApplicationContext、XmlWebApplicationContext 和 FileSystemXmlApplicationContext。我用过的只有这三个。
If your developing a web app, it's safe to say you'll need to use XmlWebApplicationContext.
如果您正在开发 Web 应用程序,可以肯定地说您需要使用 XmlWebApplicationContext。
If you want your beans to be aware of Spring, you can have them implement BeanFactoryAware and/or ApplicationContextAware for that, so you can use either BeanFactory or ApplicationContext and choose which interface to implement.
如果您希望您的 beans 了解 Spring,您可以让它们为此实现 BeanFactoryAware 和/或 ApplicationContextAware,因此您可以使用 BeanFactory 或 ApplicationContext 并选择要实现的接口。
回答by Raman Gupta
Difference between BeanFactoryand ApplicationContextare following:
BeanFactory和ApplicationContext 的区别如下:
- BeanFactory uses lazy initialization butApplicationContext uses eager initialization. In case of BeanFactory, bean is created when you call getBeans() method, but bean is created upfront in case of ApplicationContext when the ApplicationContext object is created.
- BeanFactory explicitly provide a resource object using syntax butApplicationContext creates and manages resource objects on its own.
- BeanFactory doesnt support internatiolization butApplicationContext supports internationalization.
- With BeanFactory annotation based dependency injection is not supported butannotation based dependency injection is supported in ApplicationContext.
- BeanFactory 使用延迟初始化,而ApplicationContext 使用预先初始化。在 BeanFactory 的情况下,当您调用 getBeans() 方法时会创建 bean,但是在创建 ApplicationContext 对象时,在 ApplicationContext 的情况下会预先创建 bean。
- BeanFactory 使用语法显式提供资源对象,但ApplicationContext 自行创建和管理资源对象。
- BeanFactory 不支持国际化,但ApplicationContext 支持国际化。
- BeanFactory 不支持基于注解的依赖注入,但ApplicationContext 支持基于注解的依赖注入。
Using BeanFactory:
使用 BeanFactory:
BeanFactory beanfactory = new XMLBeanFactory(new FileSystemResource("spring.xml"));
Triangle triangle =(Triangle)beanFactory.getBean("triangle");
Using ApplicationContext:
使用应用程序上下文:
ApplicationContext context = new ClassPathXMLApplicationContext("spring.xml")
Triangle triangle =(Triangle)context.getBean("triangle");
回答by Divyesh Kanzariya
BeanFactoryand ApplicationContextboth are ways to get beans from your spring IOCcontainer but still there are some difference.
BeanFactory和ApplicationContext都是从 Spring IOC容器中获取 bean 的方法,但仍然存在一些差异。
BeanFactoryis the actual container which instantiates, configures, and manages a number of bean's. These beans are typically collaborate with one another, and thus have dependencies between themselves. These dependencies are reflected in the configuration data used by the BeanFactory.
BeanFactory是实例化、配置和管理许多 bean 的实际容器。这些 bean 通常相互协作,因此它们之间具有依赖关系。这些依赖关系反映在 BeanFactory 使用的配置数据中。
BeanFactoryand ApplicationContextboth are Java interfaces and ApplicationContext extends BeanFactory. Both of them are configuration using XML configuration files. In short BeanFactory provides basic Inversion of control(IoC) and Dependency Injection (DI) features while ApplicationContext provides advancedfeatures.
BeanFactory和ApplicationContext都是 Java 接口,ApplicationContext 扩展了 BeanFactory。它们都是使用 XML 配置文件进行配置的。简而言之 BeanFactory 提供基本的控制反转(IoC)和依赖注入(DI)功能,而 ApplicationContext 提供高级功能。
A BeanFactory is represented by the interface "org.springframework.beans.factory" Where BeanFactory, for which there are multiple implementations.
一个 BeanFactory 由接口“ org.springframework.beans.factory”表示,其中 BeanFactory 有多个实现。
ClassPathResource resource = new ClassPathResource("appConfig.xml");
XmlBeanFactory factory = new XmlBeanFactory(resource);
DIFFERENCE
区别
BeanFactoryinstantiate bean when you call getBean()method while ApplicationContext instantiate Singleton bean when container is started, It doesn't wait for getBean() to be called.
BeanFactorydoesn't provide support for internationalization but ApplicationContextprovides support for it.
Another difference between BeanFactoryvs ApplicationContextis ability to publish event to beans that are registered as listener.
One of the popular implementation of BeanFactoryinterface is XMLBeanFactorywhile one of the popular implementation of ApplicationContextinterface is ClassPathXmlApplicationContext.
If you are using auto wiring and using BeanFactorythan you need to register AutoWiredBeanPostProcessorusing API which you can configure in XML if you are using ApplicationContext. In summary BeanFactoryis OK for testing and non production use but ApplicationContextis more feature rich container implementation and should be favored over BeanFactory
BeanFactoryby default its support Lazyloading and ApplicationContextby default support Aggresiveloading.
BeanFactory在调用getBean()方法时实例化 bean,而 ApplicationContext 在容器启动时实例化 Singleton bean,它不等待 getBean() 被调用。
BeanFactory不提供对国际化的支持,但ApplicationContext提供了支持。
BeanFactory与ApplicationContext之间的另一个区别是能够将事件发布到注册为侦听器的 bean。
BeanFactory接口的流行实现之一是XMLBeanFactory而ApplicationContext接口的流行实现之一是ClassPathXmlApplicationContext。
如果您使用自动连接并使用BeanFactory,那么您需要使用 API注册AutoWiredBeanPostProcessor,如果您使用ApplicationContext ,则可以在 XML 中进行配置 。总之BeanFactory可以用于测试和非生产用途,但ApplicationContext是功能更丰富的容器实现,应该比BeanFactory更受青睐
BeanFactory默认支持Lazy加载,ApplicationContext默认支持Aggressive加载。


