Spring BeanFactory and ApplicationContext are interfaces responsible for configuring a Spring application. BeanFactory is the main interface for accessing the spring container and acts as a central registry of all components. BeanFactory along with its subinterfaces are also responsible for implementing dependency injection. An ApplicationContext extends the functionality of a BeanFactory and provides additional methods.
BeanFactory vs ApplicationContext
As seen in the class diagram below an ApplicationContext is an extension of BeanFactory. It adds additional functionalities such as messaging and internationalization support, publishing events, resolving location patterns to resources and a reference to the Environment.
Spring BeanFactory and ApplicationContext class hierarchy
Here’s a class diagram of the BeanFactory hierarchy. Note that we have shown only interesting interfaces.
The important classes have been colored in yellow. Let’s look at some of the classes in details
Spring bean
Each object that spring manages is called a bean. Spring takes care of creating an object, injecting its dependencies and calling lifecycle methods on those objects. It also manages the number of instances of a given object. For example, a singleton scoped bean has only one instance of an object throughout the life of an application. There are various ways to provide the definition of a bean (an object that spring manages). For example, we can use an XML file to specify the beans or use a Java class or use annotations.
ClassPathXmlApplicationContext
This class can be used to read bean definition from an XML file that is in the classpath. To override the locations for config files override the getConfigLocations method. If there are multiple files with same bean definition then the configuration from the file loaded last wind.
In the example below, we use an XML file to create two beans – School and Dean. The ‘dean’ bean is injected into the school bean in the XML configuration. The main class that loads the xml file using ClassPathXmlApplicationContext The School and Dean class The next way to load Spring bean configuration is to use AnnotationConfigApplicationContext. These loads bean definitions from classes annotated with @Configuration, @Component or JSR-330 compliant @Inject annotations. The classes containing the annotations can be registered using the In the example below, we read bean configuration information from a Java class file that has been annotated with @Configuration. To configure a bean, annotate a method with @Bean and in that method create the return an instance of the required object. Any dependent bean can be obtained from the same class. Similar to the earlier example, we create a bean for a School class and inject a Principal class into that bean. The Configuration class Please see the previous example above for the definition of School and Principal class. The other important ApplicationContexts are the XmlWebApplicationContext and AnnotationConfigWebApplicationContext. They are both used for a web application and provide additional functionalities such as the getServletContext() method. We will look at them in a later tutorial.
Here’s the XML file:
package com.studytrails;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class XmlApplicationContextTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("SpringConfig.xml");
System.out.println(((Dean) context.getBean("dean")).getName()); // prints McArthur
System.out.println(context.getBean(Dean.class).getName());// prints McArthur
}
}
package com.studytrails;
public class School {
private Dean dean;
public Dean getDean() {
return dean;
}
public void setDean(Dean dean) {
this.dean = dean;
}
}
package com.studytrails;
public class Dean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
AnnotationConfigApplicationContext
register(...)
method or can be scanned using the scan()
method.Example of AnnotationConfigApplicationContext
Here’s the main class
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AnnotationApplicationContextTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SchoolConfig.class);
System.out.println(context.getBean(School.class).getDean().getName()); // prints McArthur
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SchoolConfig {
@Bean(name = "school")
public School getSchool() {
School school = new School();
school.setDean(getDean());
return school;
}
@Bean(name = "dean")
public Dean getDean() {
Dean dean = new Dean();
dean.setName("McArthur");
return dean;
}
}