@Bean Annotation in Spring:
@Bean is used to register a bean in spring container. There are two kind of configuration we can do in Spring Framework, one is using the xml bean configuration file and second is using the java configuration file. Here we will talk about second option, so when we do configuration using the java class, we use
@Configuration annotation on the top of the class name.
@Bean is mostly used with the
@Configuration annotation.
@Bean annotation tells the container that this bean is registered and should be created, instantiated disposable. Container does all the life cycle events. Spring container first search the beans which is configured using annotation and then search in xml bean configuration file.
Example of @Bean annotaion:
Department.java
package com.evon.example.beanAnnotaion;
public class Department {
private Long deptId;
private String deptName;
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
}
ConfigurationUtil.java
package com.evon.example.beanAnnotaion;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConfigurationUtil {
@Bean(name="departmentBean")
public Department department(){
Department dept= new Department();
dept.setDeptId(2546l);
dept.setDeptName("Information Technology");
return dept;
}
}
Main.java
package com.evon.example.beanAnnotaion;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigurationUtil.class);
Department dept = (Department)ctx.getBean("departmentBean");
System.out.println("Department ID : "+dept.getDeptId());
System.out.println("Department Name "+dept.getDeptName());
}
}
Output:
Department ID : 2546
Department Name Information Technology
We can also configure the scope of a bean using the @Scope annotation. Default the scope of a bean is singleton, we can have different scopes as per our need like prototype, request, session and globalSession. We can define it as follows :
@Configuration
public class ConfigurationUtil {
@Bean(name="departmentBean")
@Scope("prototype")
public Department department(){
Department dept= new Department();
dept.setDeptId(2546l);
dept.setDeptName("Information Technology");
return dept;
}
}
Injecting Dependencies :
In case of dependency injection, where one object is depends on another object we can inject bean to another bean using java configuration also. We can do it in both the ways using constructor and setter methods. Following is the example of DI using setter method.
Example of Injecting Dependencies :
Employee.java
package com.evon.example.beanAnnotaion;
public class Employee {
private int empId;
private String empName;
private Department department;
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}
ConfigurationUtil.java
package com.evon.example.beanAnnotaion;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConfigurationUtil {
@Bean(name="departmentBean")
public Department department(){
Department dept= new Department();
dept.setDeptId(2546l);
dept.setDeptName("Information Technology");
return dept;
}
@Bean(name="employeeBean")
public Employee employee(){
Employee emp= new Employee();
emp.setEmpId(236);
emp.setEmpName("John Brose");
emp.setDepartment(department());
return emp;
}
}
Main.java
package com.evon.example.beanAnnotaion;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigurationUtil.class);
Employee emp = (Employee)ctx.getBean("employeeBean");
System.out.println("Employee ID : "+ emp.getEmpId());
System.out.println("Employee Name : "+ emp.getEmpName());
System.out.println("Department Name : "+emp.getDepartment().getDeptName());
}
}
Output :
Employee ID : 236
Employee Name : John Brose
Department Name : Information Technology
Receiving Lifecycle Callbacks :
Beans configured in Java class supports the normal life-cycle callbacks. All the classes registered in the Java config file using @Bean annotation can use the @PostConstruct and @PreDestroy annotations.
Bean life cycle callbacks which is supported by Spring Framework also works with java configured beans. Bean can implements InitializingBean, DisposableBean and container will responsible to call their respective methods.
Example of Lifecycle Callbacks : In the above example change the Employee.java
package com.evon.example.beanAnnotaion;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class Employee {
private int empId;
private String empName;
private Department department;
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
@PostConstruct
public void init(){
System.out.println("This is init method.");
}
@PreDestroy
public void destroy(){
System.out.println("This is PreDestroy method.");
}
}
And run the program again, you will see the following output :
This is init method.
Employee ID : 236
Employee Name : John Brose
Department Name Information Technology
This is PreDestroy method.
Here we can see that before initializing the Employee bean the init() method is called and before disposing the bean destroy method is called automatically by the container. If you want to define callback methods externally and want to call those methods then you just need to use initMethod and destroyMethod in java configuration, same as init-method and destroy-method in xml bean configuration.
For example remove the @PostConstruct and @PreDestroy annotations from above example and call those method explicitly using following code:
package com.evon.example.beanAnnotaion;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConfigurationUtil {
@Bean(name="departmentBean")
public Department department(){
Department dept= new Department();
dept.setDeptId(2546l);
dept.setDeptName("Information Technology");
return dept;
}
@Bean(name="employeeBean", initMethod="init", destroyMethod="destroy")
public Employee employee(){
Employee emp= new Employee();
emp.setEmpId(236);
emp.setEmpName("John Brose");
emp.setDepartment(department());
return emp;
}
}
Above we see that instead of using spring callback methods we use our simple methods or user defined lifecycle callback methods and call it using initMethod and destroyMethod. The output will be the same :
This is init method.
Employee ID : 236
Employee Name : John Brose
Department Name Information Technology
This is PreDestroy method.
0 Comment(s)