BeanFactory vs ApplicationContext
Solution 1
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:
Bean Factory
- Bean instantiation/wiring
Application Context
- Bean instantiation/wiring
- Automatic BeanPostProcessor registration
- Automatic BeanFactoryPostProcessor registration
- Convenient MessageSource access (for i18n)
- ApplicationEvent publication
So if you need any of the points presented on the Application Context side, you should use ApplicationContext.
Solution 2
Spring provides two kinds of IOC container, one is
XMLBeanFactory
and other isApplicationContext
.
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
Beans loaded through the full path. -
ClassPathXmlApplicationContext
Beans loaded through the CLASSPATH -
XMLWebApplicationContext
andAnnotationConfigWebApplicationContext
beans loaded through the web application context. -
AnnotationConfigApplicationContext
Loading Spring beans from Annotation based configuration.
example:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
-
ApplicationContext
is the container initialized by aContextLoaderListener
orContextLoaderServlet
defined in aweb.xml
andContextLoaderPlugin
defined instruts-config.xml
.
Note: XmlBeanFactory
is deprecated as of Spring 3.1 in favor of DefaultListableBeanFactory
and XmlBeanDefinitionReader
.
Solution 3
To me, the primary difference to choose BeanFactory
over ApplicationContext
seems to be that ApplicationContext
will pre-instantiate all of the beans. From the Spring docs:
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.
Given this, I initially chose BeanFactory
for 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 -- BeanFactory
doesn't support classpath
XML configuration. So BeanFactory
and ApplicationContext
each provide a crucial feature I wanted, but neither did both.
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.
What I ended up doing was extending ClassPathXmlApplicationContext
to lazily load beans for use in tests like so:
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);
}
}
}
Solution 4
To add onto what Miguel Ping answered, here is another section from the documentation that answers this as well:
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.
(posting this for any future Spring novices who might read this question)
Solution 5
ApplicationContext
is more preferred way thanBeanFactory
In new Spring versions
BeanFactory
is replaced withApplicationContext
. But stillBeanFactory
exists for backward compatability-
ApplicationContext extends BeanFactory
and 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
Related videos on Youtube
Comments
-
matt b about 3 years
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.
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
BeanFactory
andApplicationContext
- which is appropriate to use in which conditions?I understand that
ApplicationContext
extendsBeanFactory
, but if I'm just writing a simple main method, do I need the extra functionality thatApplicationContext
provides? And just exactly what kind of extra functionality doesApplicationContext
provide?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?
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
?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.
-
MetroidFan2002 over 15 yearsBeanFactory is lightweight, but if you're going to be using Spring "for real", you may as well go with the ApplicationContext: there is very little overhead involved if you don't use its fancy features, but they're still available for if/when you do use them.
-
matt b over 14 yearsI would argue that if your unit tests are loading up your full Spring context, they aren't "unit tests", but integration tests.
-
Lyle over 14 yearsGood point. In my case I actually needed to load beans from the context for performance and integration tests, and wrote "unit tests" out of habit. I've edited my answer accordingly.
-
M. Atif Riaz over 10 yearsThis is relevant section from documentation As the
ApplicationContext
includes all functionality of theBeanFactory
, it is generally recommended that it be used in preference to theBeanFactory
, except for a few limited situations such as in anApplet
, where memory consumption might be critical and a few extra kilobytes might make a difference. However, for most 'typical' enterprise applications and systems, theApplicationContext
is what you will want to use. -
Abidi over 10 yearsWhat does it mean when you say "automatic BeanPostPorcessor regisgration"? Does it mean that class doesn't have to implement that interface?
-
Jackie over 10 yearsI don't see any practical meaning of beanFactory, in presence of ApplicationContext.
-
Aritz almost 10 years
BeanFactory doesn't support classpath XML configuration.
I think it does: stackoverflow.com/questions/5231371/… -
ininprsr over 8 yearsApplicationContext supports AOP against BeanFactory.
-
Jeffrey Bosboom over 8 yearsStack Overflow isn't a forum, so I've edited your answer to more directly respond to the question and avoid inviting discussion.
-
Half Blood Prince about 7 yearsWith
BeanFactory
we can pass constructor parameters dynamically but withApplicationContext
we can't do that. -
pjj over 6 yearsCan you please explain your #1 more clearly, if I have defined a singleton bean in my spring config file then spring container will create a singleton of the same, how does it matter whether BeanFactory or ApplicationContext is there.
-
Zoltán Raffai almost 6 yearsVery simple and straightforward answer. Here you can see more about the most used implementations with examples: zoltanraffai.com/blog/…
-
Akhil Jain almost 6 yearsits AnnotationConfigApplicationContext not -AnnotationConfigWebApplicationContext- below ClassPathXmlApplicationContext in the diagram
-
mark.monteiro almost 6 yearsAn important note from the linked Spring documentation: "Versions of Spring 2.0 and above make heavy use of the BeanPostProcessor extension point (to effect proxying and suchlike), and if you are using just a plain BeanFactory then a fair amount of support such as transactions and AOP will not take effect (at least not without some extra steps on your part)."
-
dhana1310 over 4 yearsPoint a and f are same. Can be combined together.
-
Aniket about 3 years@pjj, when u create an object of
BeanFactory bf = new XmlBeanFactory(...)
, at this point of time the BeanFactory will not instantiate any beans but instead when you do abf.getBean("myBeanRefId");
only then the container will construct your specific beans and return the reference to your bean which is Lazy loading. Whereas for ApplicationContext, when u create the object forApplicationContext ac = new ClassPathXmlApplicationContext(...);
, at this point of time itself, the container instantiates all the beans mentioned in the configuration XML file which is Eager loading. -
Vishal A over 2 yearsThanks for the figurative explanation. This helps !