Introduction to Spring Bean

In this tutorial you are going to learn what Sping Bean is and how to use it.

spring-featured-image

What is Spring Bean?

Beans are the objects that construct the application and are managed by the Spring IoC container. The formal definition from the Spring Framework documentation is:
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container.

If you are not familiar with Spring IoC container, I strongly encourage you to click here. You will get redirected to the article I have written about the topic.

The definition of bean contains something called configuration metadata. It is needed for the container to know how to create a bean, the bean’s lifecycle details and finally, the bean’s dependencies.

How to declare a Bean?

We can declare a bean simply by using the @Bean annotation. An example of declaring a method with the @Bean annotation:

@Configuration
public class DemoConfig{
    @Bean
    public String demoService() {
        return "Hello World!";
    }
}

It is important to mention that when JavaConfig encounters a @Bean method, it will execute that method and the return value will be registered as a bean within BeanFactory.




Domain classes

Let’s say we have a class called Company that has a constructor which assigns an Employee instance to an instance variable. It also has the corresponding setter and getter methods for that employee.

Company.java

public class Company {
    private Employee employee;
 
    public Company(Employee employee) {
        this.employee = employee;
    }
	
	public void setEmployee(Employee employee) {
		this.employee = employee;
	}
			
	public Employee getEmployee() {
		return employee;
	}
 }

Now, let’s see how each employee is constructed:

public class Employee {
   private int id;
   private String firstName;
   private String lastName;

   public Employee(int id, String firstName, String lastName) {
      this.id = id;
      this.firstName = firstName;
      this.lastName = lastName;
   }

   public setFirstName(String fName) {
      firstName = fName;
   }

   public setLastName(String lName) {
      lastName = lName;
   }
   
   public int getId() {
      return id;
   }
   
   public String getFirstName() {
      return firstName;
   }
   
   public String getLastName() {
      return lastName;
   }
}

A standard method with a single constructor and setters/getters methods.

From the two classes above, how would you assign the employee to a particular company? Well, first you will instantiate an Employee object, then you will instantiate a Company object and you will pass the Employee object as a constructor parameter. Like so:

Emplyoee employee = new Employee(1, "John", "Smith");
Company company = new Company(employee);

This is the usual way of doing it. What’s the problem with this approach? Imagine if we hundreds of classes. It would be hardly manageable, probably even unmanageable.

Due to that issue, we have Inversion of Control. An object can retrieve its dependencies from an IoC container instead of constructing the dependencies by itself.

Let’s see how we can improve the example above by including the main topic of this article – @Bean.

AppConfig.java

@Configuration
@ComponentScan(basePackageClasses = Company.class)
public class AppConfig {
    @Bean
    public Employee getEmployee() {
        return new Eployee(1, "John", "Smith");
    }
}

Now that we have our configuration class written up, we need to create an instance of the AnnotationConfigApplicationContext class:

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

We are now done! We have made the IoC Container initialize the beans. There’s one more thing left to do. Check whether the beans are created correctly.

To do that, simply instantiate a Company instance and then we can use the assertEquals method to check for correctnes.

Company company = context.getBean("company", Company.class);
assertEquals("John", company.getEmployee().getFirstName());
assertEquals(1, company.getEmployee().getId());

Leave a Reply

avatar