A Beginners Guide To Spring Beans and IoC

C. R. Raja Vignesh
Javarevisited
Published in
6 min readMar 2, 2022

The Beans for the backbone of the Spring framework. All of the objects, resources are managed in the form of beans.

According to the official documentation in spring.io,

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 managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.

The spring beans refer to the java objects that are created and managed by the Spring IOC container. To understand the use of spring beans we have to first know about IOC — Inversion of Control.

What is Inversion Of Control?

The inversion Of Control forms the core of the Spring Framework. It refers to the mechanism in which the control of the objects and portions of the code is handed over to a framework or a container and is most commonly used in Object-Oriented Programming. The spring container keeps track of all of the objects and their dependencies and makes them available to the program whenever required. It is responsible for maintaining the lifecycle of all of the objects.

Dependency Injection

This inversion of control is achieved by the IOC Containers in Spring by the use of a process called Dependency Injection. It is the mechanism used to achieve loose coupling between the objects by creating and injecting the necessary dependencies required to create an object during the runtime. Instead of manually injecting the dependencies, this is achieved using the IoC containers in spring.

The IOC container is implemented using the ApplicationContext and the BeanFactory Interfaces and contains all of the necessary details of the application like bean definitions, information about instantiating, managing, and destroying objects, etc.

So, how are the dependencies injected into the objects in Spring?

The dependencies can be injected into the objects in runtime in three different ways:

  • Constructor Injection: This is achieved by defining a constructor for the objects which takes the values for all of the necessary dependencies as input.
@Autowired
public OutputService(TimerService timeService, GreetingService greetingService, String name) {
this.timeService=timeService;
this.greetingService=greetingService;
this.name=name;
}
  • Setter Injection: This is achieved by defining a setter for all of the necessary dependencies in the object.
@Autowired
public void setTimeService(TimerService timeService) {
this.timeService = timeService;
}

@Autowired
public void setGreetingService(GreetingService greetingService) {
this.greetingService = greetingService;
}
  • Field Injection: In this approach, we can inject the dependencies in the field level by using the @Autowired annotation over the required fields in spring. (Available only with the Annotation based configuration)
@Autowired
private TimerService timeService;
@Autowired
private GreetingService greetingService;

In the case of an xml based configuration, the autowiring can be enabled by specifying the autowire property for the bean and specifying the type for it.

In general, all three of the approaches can be used for dependency injection. however, it is preferred to select any one of them and use the same in the project for consistency.

Configuring a Spring bean

XML Based Configuration

Traditionally, they are configured in the XML file that contains the context for the spring application.

<bean name=”processor” class=”com.example.com.MainProcessor”></bean>

A sample XML file with a bean definition:

The bean definitions or the application context can be loaded using the ClassPathXmlApplicationContext implementation of the Application Context.

Java Based Configuration

However, they can also be created using the @Bean annotation in the newer versions of the Spring framework

@Bean
public MainProcessor processor() {
return new MainProcessor();
}

In both of the cases, we are declaring a new bean for the class MainProcessor. In the annotation-based configuration, since we have not provided any specific name for the bean, the spring will automatically use the method name for the bean while creating a new bean for this class (The first letter of the method name will always be converted to lowercase). However, we can explicitly provide the bean name while declaring it as @Bean(name=”customName”).

@Bean(name=”customName”)
public MainProcessor processor() {
return new MainProcessor();
}

This is an example of java based configuration equivalent for the above XML-based example.

In this case, the Context can be loaded using the AnnotationConfigApplicationContext implementation of the Application Context by specifying the configuration class.

Annotation Based Configuration

Spring 2.5 introduced the newer approach to configuring the beans thereby removing the need for the XML file-based configuration. It introduced several new annotations such as:

  • @Component: The Component annotation is used to mark the class to be scanned and then managed by the Spring IOC containers during Component Scanning instead of manually creating Beans for the classes.
  • @Service, @Repository, @Controller, and @RestController: These are the specialized forms of the @Component annotation and provide better readability and modularity between the different layers of the application.

@Service — Used to Represent the service layer,
@Repository — Used to Represent the Data Access Layer (DAO),
@Controller — Used to represent the Presentation Layer (For handling requests from UI and in MVC design),
@RestController— Used to Represent the Presentation Layer with Rest endpoints.

The component itself may be used in place of the other annotations and the application may work fine but there may be some unexpected behaviors. For example, The PersistenceExceptionTranslationPostProcessor which is used to catch the Persistence Specific Exceptions and throw them as spring’s unified runtime exceptions acts as an advisor to the classes that are annotated with the @Repository annotation. They also provide an opportunity to implement the pointcuts in AOP.

Now, in order to make spring automatically scan a package and configure the beans by enabling the Component Scan property. This can be done

  • Directly from the XML file by adding an additional attribute:

<context:component-scan base-package="com.infotrends.in.sports"/>

On using this approach, we can use the

  • Or by using the @ComponentScan Annotation.
@ComponentScan(“com.infotrends.in.sports.annotations”)
public class ConfigurationClassName {
}

The application context can be directly loaded from a java file by using the @ComponentScan and @Configuration annotations and the AnnotationConfigApplicationContext implementation of the Application Context.

In this case, we can use the AnnotationConfigApplicationContext implementation for creating the Application Context.

Different Ways Of Autowiring the Beans

As mentioned previously, by using autowiring, we do not have to explicitly pass the reference to the different dependent dependencies needed while bean creation. It will automatically be managed by the Spring IOC container. If no suitable bean is found for Autowiring, then the NoSuchBeanDefinitionException exception is thrown

The different ways of configuring the Autowiring are:

  • no: For disabling autowiring in the bean and we have to explicitly provide the reference to the dependent beans. This is the default behavior for XML.
  • byName: In this case, the spring will search for a bean created with the same name as the property that has to be set.
  • byType: In this case, the spring will search for a bean of the same type as the property that has to be set. If there are more than one bean for the required type, then spring will throw a NoUniqueBeanDefinitionException exception. This is the default configuration used in @Autowired annotation if no specific type is provided.
  • Constructor: In this case, the spring will look for the required bean types based on the constructor arguments.

For Example,

  • A bean definition in an xml file looks like this without Autowiring:
<bean id="is24hrFormat" class="java.lang.Boolean">
<constructor-arg type="java.lang.Boolean" value="#{new Boolean(environment['spring.profiles.active']!='dev')}"/>
</bean>
<bean id="timerService" class="com.infotrends.in.Springbasics.service.TimerService;">
<constructor-arg ref="is24hrFormat"/>
</bean>
<bean id="greetingService" class="com.infotrends.in.Springbasics.service.GreetingService">
<constructor-arg index="0" value="${app.greeting}"/>
</bean>
<bean id="outputService" class="com.infotrends.in.Springbasics.service.OutputService">
<constructor-arg index="0" ref="timerService"/>
<constructor-arg index="1" ref="greetingService"/>
<constructor-arg index="2" value="${app.name}"/>
</bean>
  • However, using Autowiring, we can directly skip passing the reference to the timerService and greetingService beans as shown bellow ()
<bean id="is24hrFormat" class="java.lang.Boolean">
<constructor-arg type="java.lang.Boolean" value="#{new Boolean(environment['spring.profiles.active']!='dev')}"/>
</bean>
<bean id="timerService" class="com.infotrends.in.Springbasics.service.TimerService;">
<constructor-arg ref="is24hrFormat"/>
</bean>
<bean id="greetingService" class="com.infotrends.in.Springbasics.service.GreetingService">
<constructor-arg index="0" value="${app.greeting}"/>
</bean>
<bean id="outputService" class="com.infotrends.in.Springbasics.service.OutputService" autowire = "byType">
<constructor-arg index="2" value="${app.name}"/>
</bean>

This is an example of the autowire configuration byType.

Conclusion

This article gave a brief about the Spring bean and the different ways to use them in spring based using XML or Annotation based configurations.

You can find the project used for the examples in the GitHub repo https://github.com/Vicky-cmd/SpringMVC

--

--

C. R. Raja Vignesh
Javarevisited

Currently Working as a Developer in Tata Consultancy Services on Spring Boot Applications & Microservices. Interested to learn new things about cloud and DevOps