![]() |
VOOZH | about |
The @Bean annotation in Spring is a powerful way to define and manage beans in a Spring application. Unlike @Component, which relies on class-level scanning, @Bean explicitly declares beans inside @Configuration classes, offering greater flexibility in object creation. In this article, we will explore how @Bean works, its advantages, and how to use it for dependency injection, manual bean creation, and Spring IoC container management with practical examples.
Prerequisites:
Before diving into the @Bean annotation, it is recommended to have a basic understanding of the following Spring annotations:
The @Bean Annotation in Spring is used to define a method that produces a bean to be managed by the Spring IOC (Inversion of Control) container. When we annotate a method with @Bean, we are telling Spring to manage this object (The method will return an instance of a class), and Spring will treat that instance as a bean in its container. These beans can be injected into other components such as service, controllers, or repositories through dependency injection.
Key points about @Bean Annotation:
Example: This example demonstrates how to define a bean (MyService) in a Spring configuration class using the @Bean annotation so Spring manages its creation and lifecycle.
Explanation: In the above code, the myService() method is annotated with @Bean annotation that means it provides a bean of type MyService. Spring will call this method to create a object and then the object will then be added to the Spring container. The object can be injected and used in other components of the Spring application.
Let's now create a simple Spring project to demonstrate the use of the @Bean annotation.
Suppose we already have a Java project and all the Spring JAR files are imported into the project. First, we are going to create a simple class named as College and inside the class we have a simple method.
Here, the @Component annotation tells the Spring to treat college class as a bean, which then can be automatically managed by the Spring container.
College.java:
Now let’s create a Configuration class named CollegeConfig.
Configuration Class:
But we do not want to use the @Component and @ComponentScan annotations to create the beans. Let’s discuss another way of doing the same task.
We can manually create the beans in a configuration class using the @Bean annotation. In the CollegeConfig class, we will use @Bean annotation to define a beans for the class. Please refer to the comments for a better understanding.
@Bean
// Here the method name is the
// bean id/bean name
public College collegeBean()
{
// Returns the College object
return new College();
}
Here, the @Configuration annotation indicates that this class is a configuration class and the @Bean annotation is used to define a bean.
CollegeConfig.java:
Note: Whenever you are using the @Bean annotation to create the bean you don’t need to use the @ComponentScan annotation inside your configuration class.
Now, let’s create a Main class to test our application.
Application Class:
Output:
Test College MethodNote: Now let’s remove the @Bean annotation before the collegeBean() method and run the program again we are going to get the NoSuchBeanDefinitionException
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'collegeBean' available
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:863)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1344)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:309)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1160)
at BeanAnnotation.Main.main(Main.java:15)
So the point is to make the collegeBean() method work like a bean you need to define the @Bean annotation before that particular method.
Now the question arises can we give a different Bean ID for the collegeBean() method? The answer is YES, we can. We can modify our code something like this
So, in order to test our application, we also need to do changes in the Main.java file
Application class:
One more interesting thing is we can give multiple names to this particular collegeBean() method. So further we can modify our code something like this.
@Bean(name = {"myCollegeBean", "yourCollegeBean"})
public College collegeBean()
{
return new College();
}
Similary, in order to run the application, we need to modify Main.java file
Now let’s discuss another scenario. Suppose we have a dependency class named Principal inside our College class then what to do? So the scenario is like this. We have a class named Principal.java and we have defined a simple method inside this.
Example: Here, we have created a simple Principle class with a method principalInfo() that prints a message.
The College class looks something like below:
So now we want to do the dependency injection. So we can do it in 2 ways as listed later implemented as shown below:
In this approach, we inject the dependency using a constructor. So our modified College.java file is,
Now come to the CollegeConfig.java file and the modified CollegeConfig.java is given below. Refer to the comments for better understanding.
And finally Below is the code for the Main.java file.
Output:
Hi, I am your principal
Test College Method
In this approach, we inject the dependency using a setter method. So our modified College.java file is as follows:
College.java:
Now come to the CollegeConfig.java file and the modified CollegeConfig.java is given below as follows:
CollegeConfig.java:
And finally Below is the code for the Main.java file.
Application Class:
Output:
Hi, I am your principal
Test College Method