In Spring, we can configure the beans in two ways: in XML files or using @Bean in @Configuration annotated classes. In this tutorial, we will explore both ways to create and manage the beans.
1. Maven
To create the spring application context, which is capable of creating and managing beans, we need minimum of three maven dependencies i.e. spring-core, spring-beans and spring-context.
- The spring-core module has the most basic classes required to work with other spring modules.
- The spring-beans module provides
org.springframework.beans.factory.BeanFactory
interface which is required to work with spring beans. - The spring-context module provides
org.springframework.context.ApplicationContext
interface which enables additional features such as message resources, AOP capabilities, specific types of application contexts and bean lifecycle event listeners.
<properties>
<spring.version>6.0.8</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
2. Beans using XML Configuration
2.1. Bean Definitions
When using XML files, we can define the beans either in a single file or we can distribute the beans in separate files for better code structure. Either way, the bean definitions will be created the same.
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="operations" class="com.howtodoinjava.core.demo.beans.Operations"></bean>
<bean id="employee" class="com.howtodoinjava.core.demo.beans.Employee"></bean>
<bean id="department" class="com.howtodoinjava.core.demo.beans.Department"></bean>
</beans>
If we have created multiple bean definition files, we can import the files in the current file as follows:
<beans>
<import resource="employee.xml"/>
<import resource="department.xml"/>
<bean id="operations" class="com.howtodoinjava.spring.beans.Operations"></bean>
</beans>
2.2. Loading Beans into Context
To load the bean definitions files and thus initialize beans, we can pass the bean definition file name into the constructor of any one of the ApplicationContext implementations.
- ClassPathXmlApplicationContext
- FileSystemXmlApplicationContext
- XmlWebApplicationContext
Following is an example of loading the beans.xml file into ClassPathXmlApplicationContext. Note that the bean definition file is located at '/src/main/resources/beans.xml'
.
ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:beans.xml");
Employee employee = ctx.getBean(Employee.class);
Department department = ctx.getBean(Department.class);
Operations operations = ctx.getBean(Operations.class);
Program output:
Jan 02, 2018 3:10:27 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
Jan 02, 2018 3:10:27 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [employee.xml]
Jan 02, 2018 3:10:27 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [department.xml]
3. Beans using Annotation Configuration
When Spring loads, Java beans are scanned in the following places:
- All @Bean definitions in @Configuration annotated classes
- If component scanning is enabled, all stereo-type annotated (such as @Component) classes
3.1. Annotation Configuration with Component Scanning
When component scanning is enabled, we can define the beans using one of the following annotations as appropriate.
@Component
@Repository
@Service
@Controller
@RestController
@Configuration
@ComponentScan(basePackages = "com.howtodoinjava.spring")
public class AppConfig {
}
package com.howtodoinjava.spring.service;
@Service
public class EmployeeManager {
public Employee create(Employee employee) {
//...
}
}
Now we can load the beans in context using AnnotationConfigApplicationContext as follows:
//Method 1
//ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
//Method 2
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
EmployeeManager empManager = ctx.getBean(EmployeeManager.class);
Employee emp = empManager.create();
3.2. Using @Bean and @Configuration Annotations
Instead of annotating the classes with Spring annotations, we can declare them as Spring bean in the configuration class:
@Configuration
public class AppConfig {
@Bean
public EmployeeManager employeeManager() {
return new EmployeeManager();
}
}
Now we can load this bean into the application context as follows:
//Method 1
//ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
//Method 2
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
EmployeeManager empManager = ctx.getBean(EmployeeManager.class);
Employee emp = empManager.create();
Happy Learning !!