Tutorial

Spring @Configuration Annotation

Published on August 3, 2022
author

Pankaj

Spring @Configuration Annotation

Spring @Configuration annotation is part of the spring core framework. Spring Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.

Spring @Configuration

Spring @Configuration annotation allows us to use annotations for dependency injection. Let’s understand how to create Spring Configuration classes. Let’s create a simple java bean class.

package com.journaldev.spring;

public class MyBean {

	public MyBean() {
		System.out.println("MyBean instance created");
	}
	
}

Before we use any of the Spring framework classes, we will have to add it’s dependencies to the maven project.

<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.0.6.RELEASE</version>
</dependency>

Now let’s create the Spring Configuration class.

package com.journaldev.spring;

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

@Configuration
public class MyConfiguration {

    @Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
}

Let’s write a simple class and configure our simple Spring configuration class.

package com.journaldev.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MySpringApp {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
		ctx.register(MyConfiguration.class);
		ctx.refresh();

		// MyBean mb1 = ctx.getBean(MyBean.class);

		// MyBean mb2 = ctx.getBean(MyBean.class);

		ctx.close();
	}

}

If you run above application, it will produce output like this:

May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy
MyBean instance created
May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy

Notice that Spring loads beans into it’s context before we have even requested it. This is to make sure all the beans are properly configured and application fail-fast if something goes wrong. Also ctx.refresh() must be called, otherwise we will get following error when we will try to get any bean from the context.

Exception in thread "main" java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext@f0f2775 has not been refreshed yet
	at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1076)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1106)
	at com.journaldev.spring.MySpringApp.main(MySpringApp.java:11)

If you uncomment the statements where I am getting MyBean instances, you will notice that it’s not calling the constructor of MyBean. It’s because the default scope of spring beans is Singleton. We can change it using @Scope annotation.

What if we remove @Configuration annotation?

What will happen if we remove the @Configuration annotation from MyConfiguration class. You will notice that it still works as expected and spring beans are registered and retrieved as singleton classes. But in this case, if we make a call to myBean() method then it will be a plain java method call and we will get a new instance of MyBean and it won’t remain singleton. To prove this point, let’s define another bean that will be using MyBean instance.

package com.journaldev.spring;

public class MyBeanConsumer {

	public MyBeanConsumer(MyBean myBean) {
		System.out.println("MyBeanConsumer created");
		System.out.println("myBean hashcode = "+myBean.hashCode());
	}

}

Our updated Spring Configuration class is:

package com.journaldev.spring;

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

//@Configuration
public class MyConfiguration {

	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean());
	}
}

Now when we run the MySpringApp class, it generates following output.

MyBean instance created
MyBean instance created
MyBeanConsumer created
myBean hashcode = 1647766367

So MyBean is not singleton anymore, now let’s annotate MyConfiguration with @Configuration annotation again and run the MySpringApp class. This time output will be like below.

MyBean instance created
MyBeanConsumer created
myBean hashcode = 1095088856

So it’s better to use @Configuration annotation with configuration classes to make sure our spring container is behaving like the way we want it to. If you don’t want to use @Configuration annotation for some weird reasons, we can still create our configuration class by not calling the myBean() method and rather using an instance variable of MyBean configured through @Autowired annotation. Something like below code will work as well.

package com.journaldev.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration
public class MyConfiguration {

	@Autowired
	MyBean myBean;
	
	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean);
	}
}

That’s all for Spring Configuration annotation, we will look into other spring annotations in future posts.

You can download the example code from our GitHub Repository.

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

Learn more about our products

About the authors
Default avatar
Pankaj

author

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.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
February 25, 2021

If I replace @Configurations with @Component it works in same way, So why we need @Configuration ?

- Shree

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    July 5, 2020

    Sorry, I should say, thank you for the examples.

    - Jason

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      July 5, 2020

      The code works, but what is not made clear (or could be made clearer) is elaborated on in more detail the spring docs -at https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Bean.html See in particular sections @Bean Methods in @Configuration Classes and @Bean Lite Mode

      - Jason

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        April 3, 2020

        did you try to write the unit test of this code?

        - memo

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          January 29, 2020

          Hi, if I comment the @Configuration, those methods with @Bean won’t be executed.

          - weizihan

            JournalDev
            DigitalOcean Employee
            DigitalOcean Employee badge
            January 10, 2020

            How can we create the two instance of singleton scope bean using annotation based configuration. In XML we can define the two bean with different ids. But how to create the different instance using annotation based config.

            - Vaibhav Bhnawat

              JournalDev
              DigitalOcean Employee
              DigitalOcean Employee badge
              November 22, 2019

              I am reading all your articles but this explanation is not good. More expectations from you :)

              - Hardik

                JournalDev
                DigitalOcean Employee
                DigitalOcean Employee badge
                May 14, 2019

                This code is not working

                - Hardik Sharma

                  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!

                  Become a contributor for community

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

                  DigitalOcean Documentation

                  Full documentation for every DigitalOcean product.

                  Resources for startups and SMBs

                  The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                  Get our newsletter

                  Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                  New accounts only. By submitting your email you agree to our Privacy Policy

                  The developer cloud

                  Scale up as you grow — whether you're running one virtual machine or ten thousand.

                  Get started for free

                  Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                  *This promotional offer applies to new accounts only.