BeanFactory vs ApplicationContext

283,962

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 is 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 Beans loaded through the full path.
  • ClassPathXmlApplicationContext Beans loaded through the CLASSPATH
  • XMLWebApplicationContext and AnnotationConfigWebApplicationContext 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 a ContextLoaderListener or ContextLoaderServlet defined in a web.xml and ContextLoaderPlugin defined in struts-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

  1. ApplicationContext is more preferred way than BeanFactory

  2. In new Spring versions BeanFactory is replaced with ApplicationContext. But still BeanFactory exists for backward compatability

  3. 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
Share:
283,962

Related videos on Youtube

matt b
Author by

matt b

Hello, world!

Updated on June 30, 2021

Comments

  • matt b
    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 and ApplicationContext - which is appropriate to use in which conditions?

    I understand that ApplicationContext extends BeanFactory, but if I'm just writing a simple main method, do I need the extra functionality that ApplicationContext provides? And just exactly what kind of extra functionality does ApplicationContext 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
    MetroidFan2002 over 15 years
    BeanFactory 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
    matt b over 14 years
    I would argue that if your unit tests are loading up your full Spring context, they aren't "unit tests", but integration tests.
  • Lyle
    Lyle over 14 years
    Good 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
    M. Atif Riaz over 10 years
    This is relevant section from documentation As the ApplicationContext includes all functionality of the BeanFactory, it is generally recommended that it be used in preference to the BeanFactory, except for a few limited situations such as in an Applet, where memory consumption might be critical and a few extra kilobytes might make a difference. However, for most 'typical' enterprise applications and systems, the ApplicationContext is what you will want to use.
  • Abidi
    Abidi over 10 years
    What does it mean when you say "automatic BeanPostPorcessor regisgration"? Does it mean that class doesn't have to implement that interface?
  • Jackie
    Jackie over 10 years
    I don't see any practical meaning of beanFactory, in presence of ApplicationContext.
  • Aritz
    Aritz almost 10 years
    BeanFactory doesn't support classpath XML configuration. I think it does: stackoverflow.com/questions/5231371/…
  • ininprsr
    ininprsr over 8 years
    ApplicationContext supports AOP against BeanFactory.
  • Jeffrey Bosboom
    Jeffrey Bosboom over 8 years
    Stack 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
    Half Blood Prince about 7 years
    With BeanFactory we can pass constructor parameters dynamically but with ApplicationContext we can't do that.
  • pjj
    pjj over 6 years
    Can 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
    Zoltán Raffai almost 6 years
    Very simple and straightforward answer. Here you can see more about the most used implementations with examples: zoltanraffai.com/blog/…
  • Akhil Jain
    Akhil Jain almost 6 years
    its AnnotationConfigApplicationContext not -AnnotationConfigWebApplicationContext- below ClassPathXmlApplicationContext in the diagram
  • mark.monteiro
    mark.monteiro almost 6 years
    An 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
    dhana1310 over 4 years
    Point a and f are same. Can be combined together.
  • Aniket
    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 a bf.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 for ApplicationContext 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
    Vishal A over 2 years
    Thanks for the figurative explanation. This helps !