Tutorial

Spring IoC, Spring Bean Example Tutorial

Published on August 3, 2022
Default avatar

By Pankaj

Spring IoC, Spring Bean Example Tutorial

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Welcome to the Spring IoC Example Tutorial. Spring Framework is built on the Inversion of Control principle. Dependency injection is the technique to implement IoC in applications.

Spring IoC

spring ioc, spring ioc example, spring ioc tutorial, spring bean Today we will look into Spring IoC Container. We will also go through Spring Bean. Below is the table to contents for quick navigation to different sections of Spring IoC tutorial.

  1. Spring IoC
  2. Spring Bean
  3. Spring Bean Scopes
  4. Spring Bean Configuration
  5. Spring IoC and Spring Bean Example
    1. XML Based Spring Bean Configuration
    2. Annotation Based Spring Bean Configuration
    3. Java Based Spring Bean Configuration

Spring IoC Container

Spring IoC is the mechanism to achieve loose-coupling between Objects dependencies. To achieve loose coupling and dynamic binding of the objects at runtime, objects dependencies are injected by other assembler objects. Spring IoC container is the program that injects dependencies into an object and make it ready for our use. We have already looked how we can use Spring Dependency Injection to implement IoC in our applications. Spring IoC container classes are part of org.springframework.beans and org.springframework.context packages. Spring IoC container provides us different ways to decouple the object dependencies. BeanFactory is the root interface of Spring IoC container. ApplicationContext is the child interface of BeanFactory interface that provide Spring AOP features, i18n etc. Some of the useful child-interfaces of ApplicationContext are ConfigurableApplicationContext and WebApplicationContext. Spring Framework provides a number of useful ApplicationContext implementation classes that we can use to get the spring context and then the Spring Bean. Some of the useful ApplicationContext implementations that we use are;

  • AnnotationConfigApplicationContext: If we are using Spring in standalone java applications and using annotations for Configuration, then we can use this to initialize the container and get the bean objects.
  • ClassPathXmlApplicationContext: If we have spring bean configuration xml file in standalone application, then we can use this class to load the file and get the container object.
  • FileSystemXmlApplicationContext: This is similar to ClassPathXmlApplicationContext except that the xml configuration file can be loaded from anywhere in the file system.
  • AnnotationConfigWebApplicationContext and XmlWebApplicationContext for web applications.

Usually, if you are working on Spring MVC application and your application is configured to use Spring Framework, Spring IoC container gets initialized when the application starts and when a bean is requested, the dependencies are injected automatically. However, for a standalone application, you need to initialize the container somewhere in the application and then use it to get the spring beans.

Spring Bean

Spring Bean is nothing special, any object in the Spring framework that we initialize through Spring container is called Spring Bean. Any normal Java POJO class can be a Spring Bean if it’s configured to be initialized via container by providing configuration metadata information.

Spring Bean Scopes

There are five scopes defined for Spring Beans.

  1. singleton - Only one instance of the bean will be created for each container. This is the default scope for the spring beans. While using this scope, make sure bean doesn’t have shared instance variables otherwise it might lead to data inconsistency issues.
  2. prototype - A new instance will be created every time the bean is requested.
  3. request - This is same as prototype scope, however it’s meant to be used for web applications. A new instance of the bean will be created for each HTTP request.
  4. session - A new bean will be created for each HTTP session by the container.
  5. global-session - This is used to create global session beans for Portlet applications.

Spring Framework is extendable and we can create our own scopes too. However, most of the times we are good with the scopes provided by the framework.

Spring Bean Configuration

Spring Framework provides three ways to configure beans to be used in the application.

  1. Annotation Based Configuration - By using @Service or @Component annotations. Scope details can be provided with @Scope annotation.
  2. XML Based Configuration - By creating Spring Configuration XML file to configure the beans. If you are using Spring MVC framework, the xml based configuration can be loaded automatically by writing some boiler plate code in web.xml file.
  3. Java Based Configuration - Starting from Spring 3.0, we can configure Spring beans using java programs. Some important annotations used for java based configuration are @Configuration, @ComponentScan and @Bean.

Spring IoC and Spring Bean Example Project

Let’s look at the different aspects of Spring IoC container and Spring Bean configurations with a simple Spring project. For my example, I am creating a Spring MVC project in Spring Tool Suite. If you are new to Spring Tool Suite and Spring MVC, please read Spring MVC Tutorial with Spring Tool Suite. The final project structure looks like below image. Spring IoC, Spring IoC Container, Spring Bean Example, Spring Bean Let’s look at different components of Spring IoC and Spring Bean project one by one.

XML Based Spring Bean Configuration

MyBean is a simple Java POJO class.

package com.journaldev.spring.beans;

public class MyBean {

	private String name;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

Spring Configuration XML File

servlet-context.xml code:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="https://www.springframework.org/schema/beans"
	xmlns:context="https://www.springframework.org/schema/context"
	xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	
	<context:component-scan base-package="com.journaldev.spring" />
	
	<beans:bean name="myBean" class="com.journaldev.spring.beans.MyBean" scope="singleton" ></beans:bean>
	
</beans:beans>

Notice that MyBean is configured using bean element with scope as singleton.

Annotation Based Spring Bean Configuration

package com.journaldev.spring.beans;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.web.context.WebApplicationContext;

@Service
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class MyAnnotatedBean {

	private int empId;

	public int getEmpId() {
		return empId;
	}

	public void setEmpId(int empId) {
		this.empId = empId;
	}
	
}

MyAnnotatedBean is configured using @Service and scope is set to Request.

Spring IoC Controller Class

HomeController class will handle the HTTP requests for the home page of the application. We will inject our Spring beans to this controller class through WebApplicationContext container.

package com.journaldev.spring.controller;

import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.journaldev.spring.beans.MyAnnotatedBean;
import com.journaldev.spring.beans.MyBean;

@Controller
@Scope("request")
public class HomeController {
		
	private MyBean myBean;
	
	private MyAnnotatedBean myAnnotatedBean;

	@Autowired
	public void setMyBean(MyBean myBean) {
		this.myBean = myBean;
	}

	@Autowired
	public void setMyAnnotatedBean(MyAnnotatedBean obj) {
		this.myAnnotatedBean = obj;
	}
	
	/**
	 * Simply selects the home view to render by returning its name.
	 */
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public String home(Locale locale, Model model) {
		System.out.println("MyBean hashcode="+myBean.hashCode());
		System.out.println("MyAnnotatedBean hashcode="+myAnnotatedBean.hashCode());
		
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
		
		String formattedDate = dateFormat.format(date);
		
		model.addAttribute("serverTime", formattedDate );
		
		return "home";
	}
	
}

Deployment Descriptor

We need to configure our application for Spring Framework so that the configuration metadata will get loaded and context will be initialized.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>
	
	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
		
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

</web-app>

Almost all the configuration above is boiler-plate code generated by STS tool automatically.

Run the Spring IoC Bean Example Application

Now when you will launch the web application, the home page will get loaded and in the console following logs will be printed when you refresh the page multiple times.

MyBean hashcode=118267258
MyAnnotatedBean hashcode=1703899856
MyBean hashcode=118267258
MyAnnotatedBean hashcode=1115599742
MyBean hashcode=118267258
MyAnnotatedBean hashcode=516457106

Notice that MyBean is configured to be a singleton, so the container is always returning the same instance and hashcode is always the same. Similarly, for each request, a new instance of MyAnnotatedBean is created with different hashcode.

Java Based Spring Bean Configuration

For standalone applications, we can use annotation based as well as XML based configuration. The only requirement is to initialize the context somewhere in the program before we use it.

package com.journaldev.spring.main;

import java.util.Date;

public class MyService {

	public void log(String msg){
		System.out.println(new Date()+"::"+msg);
	}
}

MyService is a simple java class with some methods.

package com.journaldev.spring.main;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(value="com.journaldev.spring.main")
public class MyConfiguration {

	@Bean
	public MyService getService(){
		return new MyService();
	}
}

The annotation based configuration class that will be used to initialize the Spring container.

package com.journaldev.spring.main;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MyMainClass {

	public static void main(String[] args) {
		
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
				MyConfiguration.class);
		MyService service = ctx.getBean(MyService.class);
		
		service.log("Hi");
		
		MyService newService = ctx.getBean(MyService.class);
		System.out.println("service hashcode="+service.hashCode());
		System.out.println("newService hashcode="+newService.hashCode());
		ctx.close();
	}

}

A simple test program where we are initializing the AnnotationConfigApplicationContext context and then using getBean() method to get the instance of MyService. Notice that I am calling getBean method two times and printing the hashcode. Since there is no scope defined for MyService, it should be a singleton and hence hashcode should be the same for both the instances. When we run the above application, we get following console output confirming our understanding.

Sat Dec 28 22:49:18 PST 2013::Hi
service hashcode=678984726
newService hashcode=678984726

If you are looking for XML based configuration, just create the Spring XML config file and then initialize the context with following code snippet.

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        MyService app = context.getBean(MyService.class);

That’s all for the Spring IoC example tutorial, Spring Bean Scopes and Configuration details. Download the Spring IoC and Spring Bean example project from below link and play around with it for better understanding.

Download Spring Beans Project

Reference: Spring.IO Page for IOC

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Pankaj

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
December 18, 2018

very good explanation, thank you sir

- Dileep sagar

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    September 5, 2018

    Hi , Pankaj Great explanation . Your Blog is very useful . Thank you for the examples . can you please explain more about this line significance “resourse mapping” tag in servlet-context.xml the project works fine even if this line is commented

    - Raj Gopal

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      July 28, 2017

      what is the content of is root-context.xml.

      - kamlesh

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        September 10, 2016

        Great post, I am creating 5 @Bean objects in configuration class. Even i am calling one bean object also i am getting info of all beans in console. Can we hide other beans info ?

        - Ravi

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          August 15, 2016

          Hi, congrats for your post and info, I have a question, how can I declare bean id using @Bean annotation?, because a have seen that declaring bean with @Bean annotation only sets the name attribute and not id attribute. Thanks in advance.

          - Alex

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            October 19, 2015

            If you are providing @ComponentScan with the Java class then I don’t think there is any need to provide bean definition with @Bean annotation. Better go with full automatic config when using @ComponentScan

            - infoj

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              September 14, 2015

              This is very useful for me. very easily understandable. I want complete source code for this application. Kindly send mail me.

              - hdkjasp

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                March 18, 2015

                This tutorial is very helpful me …because i have already written Spring program but i was no able to run after watch this tutorial i have run spring program…Thanks

                - varinder singh

                  JournalDev
                  DigitalOcean Employee
                  DigitalOcean Employee badge
                  March 4, 2015

                  how to find no of beans in ioc container using bean postprocessors in spring

                  - venky

                    JournalDev
                    DigitalOcean Employee
                    DigitalOcean Employee badge
                    January 24, 2015

                    very easily understandable. I want complete source code for this application. Kindly send mail me.

                    - Mannu Soni

                      Try DigitalOcean for free

                      Click below to sign up and get $200 of credit to try our products over 60 days!

                      Sign up

                      Join the Tech Talk
                      Success! Thank you! Please check your email for further details.

                      Please complete your information!

                      Get our biweekly newsletter

                      Sign up for Infrastructure as a Newsletter.

                      Hollie's Hub for Good

                      Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

                      Become a contributor

                      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                      Welcome to the developer cloud

                      DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

                      Learn more
                      DigitalOcean Cloud Control Panel