Rajinder Menu

What is ApplicationContext? What are its implementations?



ApplicationContext, like BeanFactory, is also used to represent Spring Container. It is built upon BeanFactory interface.

BeanFactory provides basic functionality while ApplicationContext provides advance features to our spring applications which make them enterprise level applications, like i18n, event publishing, JNDI access, EJB integration, Remoting etc.


ApplicationContext is always preferred over BeanFactory and is suitable for J2EE Applications. ApplicationContext includes all functionality of the BeanFactory.

ApplicationContext and Singleton beans:

While using BeanFactory, beans get instantiated when they get requested first time, like in getBean("bean_id") method, not when object of BeanFactory itself gets created. This is known as lazy-instantiation.

But while using ApplicationContext, singleton beans does not get created lazily. By default, ApplicationContext immediately instantiates the singleton beans and wire/set its properties as it's object itself gets created. So ApplicationContext loads singleton beans eagerly (pre-instantiated).

Example:


ApplicationContext acObj=new ClassPathXmlApplicationContext("beanconfig.xml");

MyBean beanObj=(MyBean)acObj.getBean("mybean");

beanObj.someMethod();

In above example we have created an ApplicationContext object acObj using one if its implementations ClassPathXmlApplicationContext which loads the configuration from source beanconfig.xml under classpath.

If we had used BeanFactory here, mybean would get instantiated when the method getBean(mybean) would  be called.

But here with ApplicationContext, instantiation of bean with id mybean does not get delayed until getBean() method is called. If scope of the bean mybean  is declared in configuration file as singleton, it will be immediately instantiated when we create ApplicationContext object acObj. So when getBean() would be called, mybean would already have got loaded and its dependencies set.

We can change this default behavior so that ApplicationContext does not load singleton beans eagerly by using  lazy-init attribute as:

<bean id="mybean" class="x.y.z..MyBean" lazy-init="true"/>

A lazy-initialized bean tells the Spring to create a bean instance when it is first requested, rather than at the time of creation of ApplicationContext object.

Implementations of ApplicationContext:

There are many implementations of ApplicationContext interface. Important ones are:

1)  ClassPathXmlApplicationContext:

It loads bean definitions from XML files located in the classpath.
           
Example1:


ApplicationContext context = new ClassPathXmlApplicationContext("myconfig.xml");



Example2:  Loading configuration from multiple files under classpath.



ApplicationContext context = new ClassPathXmlApplicationContext(
newString[]{"servicesconfig.xml","daoconfig.xml"});


2) FileSystemXmlApplicationContext:

            It loads bean definitions from XML files in the file system.
           
Example:        
           

ApplicationContext context = new FileSystemXmlApplicationContext("c:/myconfig.xml");

3)XmlWebApplicationContext:

XmlWebApplicationContext is used to represent Spring Container for web applications.By defalut Spring creates object of XmlWebApplicationContext class to represent application context/spring container for web applications.

It loads bean definitions from an XML file contained within a web application. By default it loads the configuration from file "/WEB-INF/applicationContext.xml".

If we want to load bean definitions from more than one xml files we can specify their locations in  contextConfigLocation  parameter of ContextLoaderListener or DispatcherServlet in web.xml.Read more about this here.

XmlWebApplicationContext is an implementation of WebApplicationContext interface which in turn extends ApplicationContext interface.




4)AnnotationConfigApplicationContext:

AnnotationConfigApplicationContext class is used when we are using Java-based configuration for the bean definitions instead of Xml files.

In above ApplicationContext implementations (ClassPathXmlApplicationContext, FileSystemXmlApplicationContext) we have supplied bean configuration from xml configuration files. AnnotationConfigApplicationContext class is used to create Spring container which takes bean definitions from java classes annotated with @Configuration, instead of xml files.

It is introduced in Spring 3.0.

Example:


public static void main(String[]args){

/* Creating Spring IoC Container Without XML configuration file*/

ApplicationContext context= new AnnotationConfigApplicationContext(MyConfig.class);

MyBean beanObj = context.getBean(MyBean.class);

beanObj.someMethod();
}

In above code, AnnotationConfigApplicationContext is accepting MyConfig class as input. Here we are obtaining bean definitions from a java class named MyConfig annotated with @Configuration, instead of a Xml file. MyConfig class is described as:


@Configuration
public class MyConfig{
            @Bean
            public MyBean myBeanId(){
            return new MyBean();
            }
}

By giving @Configuration annotation we are treating Myconfig class as  <beans></beans>  tag of xml file.

By giving @Bean annotation we are treating myBean() method as  <bean id="..." class="..."/>


Name of myBeanId() method will be treated as bean id.

Both @Configuration and @Bean are also introduced in Spring 3.0.

5)AnnotationConfigWebApplicationContext:

Like XmlWebApplicationContext is web counterpart for the ClassPathXmlApplicationContext and FileSystemXmlApplicationContext and is used to create application context for web  applications, similarly, AnnotationConfigWebApplicationContext is web counterpart for AnnotationConfigApplicationContext.

AnnotationConfigWebApplicationContext is used to create application context for web applications by using java clases as input for bean definitions instead of xml files.

By default Spring use XmlWebApplicationContext (an implementation of WebApplicationContext) for creating spring container in web applications. But we can change this default value to AnnotationConfigWebApplicationContext by changing the value of contextClass parameter of ContextLoaderListener or DispatcherServlet in web.xml as shown below:

For ContextLoaderListener:
<web-app>
<context-param>
<param-name>contextClass</param-name> 
<param-value>   
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value> 
</context-param> 
<context-param>
<param-name>contextConfigLocation</param-name> 
<!--MyConfig must be annotated with @Configuration-->
<param-value> MyConfig</param-value>
</context-param>
<listener>
<listener-class> org.springframework.web.context.ContextLoaderListener </listener-class>
</listener> 
</web-app> 
For  DispatcherServlet:
<web-app>
<servlet>
<servlet-name>mydispatcher</servlet-name>
<servlet-class > org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param> 
<param-name>contextClass</param-name> 
<param-value>            
 org.springframework.web.context.support.AnnotationConfigWebApplicationContext     
</param-value>
</init-param> 
<init-param>   
<param-name>contextConfigLocation</param-name>    
<!--MyConfig must be class annotated with @Configuration-->
<param-value> MyConfig </param-value>
</init-param>
</servlet>
<servlet-mapping> 
<servlet-name>mydispatcher</servlet-name>    
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
I would like to know your comments and if you liked the article then please share it on social networking buttons.

What is Bean Factory and XmlBeanFactory?


BeanFactory is represented by org.springframework.beans.factory.BeanFactory interface.It is the main and the basic  way to access the Spring container.Other ways to access the spring container such as ApplicationContext,ListableBeanFactory, ConfigurableBeanFactory etc. are built upon this BeanFactory interface (extends/implements BeanFactory interface).

BeanFactory interface provides basic functionality for the Spring Container like:

1)It provides DI / IOC mechanism for the Spring.

2)It is built upon Factory Design Pattern.

3)It loads the beans definitions and their property descriptions from some configuration source (for example, from XML configuration  file) .

4)Instantiates the beans when they are requested like beanfactory_obj.getBean("beanId").

5)Wire dependencies and properties for the beans according to their configuration defined in configuration source while instantiating the beans.

6)Manage the bean life cycle by bean lifecycle interfaces and calling initialization and destruction methods.

(Note that BeanFactory does not create the objects of beans immediately when it loads the configuration for beans from configuration source.Only bean definitions and their property descriptions are loaded. Beans themselves are instantiated  and their properties are set only when they are requested such as by getBean() method.)

BeanFactory Implementations:

The most important BeanFactory implementation is –org.springframework.beans.factory.xml.XmlBeanFactory.It reads bean definitions from an XML file.

Constructor for XmlBeanFactory:

XmlBeanFactory(Resource resource)

Example1:


BeanFactory bfObj = new XmlBeanFactory(new FileSystemResource ("c:/beansconfig.xml"));

MyBean beanObj= (MyBean) bfObj.getBean("mybean");


In above code BeanFactory object bfObj is representing a Spring IOC container.

XmlBeanFactory constructor takes an implementation of Resource interface as an argument.
Here we have used FileSystemResource which is one of the implementations of Resource interface.

The Resource interface has many implementaions. Two mainly used are:

1)org.springframework.core.io.FileSystemResource:
              Loads the resource from underlying file system.

2)org.springframework.core.io.ClassPathResource:
              Loads the resource from classpath(shown below).

Purpose of FileSystemResource is to provide the xml file with the given name from underlying file system to XmlBeanFactory.

Now,  bfObj represents a Spring Container which has loaded the bean definitions from the beansconfig.xml file.

At this point only beans definitions got loaded but bean themselves are not instantiated yet.

At the second line,

MyBean beanObj = (MyBean) bfObj.getBean("mybean");

We are requesting from spring container a bean with id "mybean". BeanFactory will read bean definition of a bean with id "mybean" from beansconfig.xml file, instantiates it and return a reference to that. Thus BeanFactory loads the beans lazily.

Example2:


ClassPathResource resorce = new ClassPathResource ("beansconfig.xml");

BeanFactory factory = new XmlBeanFactory(resource);


Example3:


ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
        new String[] {"applicationContext.xml", "applicationContext-part2.xml"});

// an ApplicationContext is also  a BeanFactory.
BeanFactory factory = (BeanFactory) appContext;


Example4:

BeanFactory factory = new XmlBeanFactory(new FileInputStream("beansconfig.xml"));???

Note: BeanFactory is not recomended for use in latest Spring versions. It is there only for backward compatability. ApplicationContext is preferred over this because ApplicationContext provides more advance level features which makes an application enterprise level application.



I would like to know your comments and if you liked the article then please share it on social networking buttons.


WebApplicationContext and XmlWebApplicationContext(applicationContexts used in a Web Applications)


In non-web applications we use ApplicationContext interface to provide beans configuration to our applications from xml files.For example:


ApplicationContext context = new FileSystemXmlApplicationContext("c:/foo.xml");


OR


ApplicationContext context = new ClassPathXmlApplicationContext("foo.xml");


Here we are using two implementations of ApplicationContext interface namely FileSystemXmlApplicationContext and ClassPathXmlApplicationContext for loading configuration from xml files.


But in web applications we use WebApplicationContext interface instead of ApplicationContext interface to provide bean configuration to our web application and to represent the spring container.


WebApplicationContext extends ApplicationContext and has some extra features necessary for web applications.


In web applications, application contexts are provided at two levels(Context Hierarchy):

1)Root application context
2)Application context specific to each servlet defined in web.xml

There is a single root context per application, while each servlet in the application (including a dispatcher servlet in the MVC framework) has its own child context.

Both contexts are represented by WebApplicationContext interface.

Each servlet specific application context inherits the configuration defined in root application context.Thus root application context is shared among all servlet specific application contexts.

 
1)Root application context:

Root application context generally contains configuration information from more than one configuration files representing different layers of application like db layer,service layer etc. Beans specific to each layer should be defined in separate configuration file.For example data access beans should reside in application-context-db.xml, service layer beans should be in application-context-service.xml

It is loaded by using ContextLoaderListener class (org.springframework.web.context.ContextLoaderListener) declared in web.xml file as.

web.xml:


<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/application-context-db.xml
/WEB-INF/applicationContext.xml
/WEB-INF/application-context-service.xml
</param-value>
</context-param>

<listener>
<listener-class> org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

ContextLoaderListener class has two context-param level parameters in web.xml:
1) contextClass  and
2) contextConfigLocation  (shown in above code)
  
contextConfigLocation:
ContextLoaderListener reads the configuration files as defined in contextConfigLocation parameter value.

In above code root application context contains configuration information from three files namely-application-context-db.xml, applicationContext.xml and application-context-service.xml.

If contextConfigLocation parameter is not defined in web.xml then by default ContextLoaderListener will read configuration from  /WEB-INF/applicationContext.xml.

contextClass:
contextClass parameter is used to specify the class which can be used to represent  application context/spring container for our web application. Any class that implements WebApplicationContext interface can be used as value for this parameter. 

If this parameter is not defined in web.xml as in above code, then by default org.springframework.web.context.support.XmlWebApplicationContext class (an implementation of WebApplicationContext interface) is used.

We can change value of this parameter as: 

<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>

AnnotationConfigWebApplicationContext is also an implementation of WebApplicationContext interface.

ContextLoaderlistener delegates this information to org.springframework.web.context.ContextLoader class in order to create root application context.


Once the context files specified in contextConfigLocation  parameter get loaded, Spring creates a WebApplicationContext object (by default XmlWebApplicationContext object) based on the bean definitions and stores it in the ServletContext of the webapplication.

We can obtain this root WebApplicationContext object from ServletContext by using org.springframework.web.context.support.WebApplicationContextUtils class as:


WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);


Now we can use this WebApplicationContext object to obtain beans in our web application as:

MyBean beanObject= (MyBean) ctx.getBean("mybeanId");

getBean() here is inhertited by WebApplicationContext by BeanFactory interface.

2)Servlet Specific Application Context:

Each servlet defined in web.xml has its own  application context  which inherits all configurations defined in root application context. For servlet-specfic contexts,by default configurations are looked up in a file named as /WEB-INF/[servlet-name]-servlet.xml.

Thus two different servlets named servlet1 and servlet2 defined in web.xml will have their separate non-shared configurations (local to their servlet contexts) loaded by default from the files /WEB-INF/servlet1-servlet.xml and /WEB-INF/servlet2-servlet.xml.

For example, suppose we have defined a dispatcherservlet in web.xml as: 

web.xml:



<web-app>
<servlet>
<servlet-name>mydispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>mydispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

</web-app>



Then spring will look for a file named as /WEB-INF/mydispatcher-servlet.xml for bean configurations.

In case of DispactherServlet, there are also two context-param level parameters:
1) contextClass  and
2) contextConfigLocation

They are defined for the same puropse as in ContextLoaderListener described above.




I would like to know your comments and if you liked the article then please share it on social networking buttons.