One of the most important annotations in spring is the @Bean annotation which is applied on a method to specify that it returns a bean to be managed by Spring context. Spring Bean annotation is usually declared in Configuration classes methods. This annotation is also a part of the spring core framework. So let’s understand @Bean Annotation with an example project.
Prerequisite:
- Spring @ComponentScan Annotation with Example
- Spring @Configuration Annotation with Example
Implementation: Project
Suppose we have already a Java project and all the Spring JAR files are imported into that project. Now let’s create a simple class named College and inside the class, we have a simple method. Below is the code for the College.java file and using the @Component and @ComponentScan annotation let’s create the bean of this college class. So we can write code for the College.java file something like this.
A. File: College.java
Java
package BeanAnnotation;
import org.springframework.stereotype.Component;
@Component ( "collegeBean" )
public class College {
public void test()
{
System.out.println( "Test College Method" );
}
}
|
Now let’s create a Configuration class named CollegeConfig. Below is the code for the CollegeConfig.java file
Configuration Class
Java
package ComponetAnnotation;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan (basePackages = "BeanAnnotation" )
public class CollegeConfig {
}
|
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. So we are going to create the spring beans using the @Bean annotation. To create the College class bean using the @Bean annotation inside the configuration class we can write something like this inside our CollegeConfig.java file. 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();
}
B. File: CollegeConfig.java
Java
package BeanAnnotation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CollegeConfig {
@Bean
public College collegeBean()
{
return new College();
}
}
|
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 to check our application let’s create a main method inside our Main class. Below is the code for the Main.java file. Comments are added inside the code to understand the code in more detail.
C. Application Class
Java
package BeanAnnotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args)
{
ApplicationContext context
= new AnnotationConfigApplicationContext(
CollegeConfig. class );
College college
= context.getBean( "collegeBean" , College. class );
college.test();
}
}
|
Output:
Test College Method
Tip: Now let’s remove the @Bean annotation before the collegeBean() method and run our program again and you can see we are going to get the “NoSuchBeanDefinitionException” exception
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.
Giving Different Bean ID/Bean Name
Now the question is can we give a different Bean ID for this collegeBean() method? Yes, we can. We can modify our code something like this.
// Annotation
@Bean(name = "myCollegeBean")
// Class
public College collegeBean()
{
return new College();
}
So whenever you want to test your application you have to also change your Main.java file to something like this.
D. Application Class
Java
package BeanAnnotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args)
{
ApplicationContext context
= new AnnotationConfigApplicationContext(
CollegeConfig. class );
College college = context.getBean( "myCollegeBean" ,
College. class );
college.test();
}
}
|
Giving Multiple Names to the Same Bean
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();
}
Similarly, you need to modify your Main.java file during the execution of your application.
Dependency Injection with @Bean Annotation
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
Java
package BeanAnnotation;
public class Principal {
public void principalInfo()
{
System.out.println( "Hi, I am your principal" );
}
}
|
And our College.class is something like this
Java
package BeanAnnotation;
public class College {
private Principal principal;
public void test()
{
principal.principalInfo();
System.out.println( "Test College Method" );
}
}
|
So now we want to do the dependency injection. So we can do it in 2 ways as listed later implemented as shown below:
- Constructor Dependency Injection (CDI)
- Setter Dependency Injection (SDI)
Way 1: Constructor Dependency Injection (CDI)
In that case, first, let’s create a constructor inside the College class. So our modified College.java file is
A. College Class
Java
package BeanAnnotation;
public class College {
private Principal principal;
public College(Principal principal)
{
this .principal = principal;
}
public void test()
{
principal.principalInfo();
System.out.println( "Test College Method" );
}
}
|
Now come to the CollegeConfig.java file and the modified CollegeConfig.java is given below. Refer to the comments for better understanding.
B. Configuration Class
Java
package BeanAnnotation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CollegeConfig {
@Bean public Principal principalBean()
{
return new Principal();
}
@Bean public College collegeBean()
{
return new College(principalBean());
}
}
|
And finally Below is the code for the Main.java file.
C. Application Class
Java
package BeanAnnotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args)
{
ApplicationContext context
= new AnnotationConfigApplicationContext(
CollegeConfig. class );
College college
= context.getBean( "collegeBean" , College. class );
college.test();
}
}
|
Output:
Hi, I am your principal
Test College Method
Way 2: Setter Dependency Injection (SDI)
In that case, first, let’s create a setter method inside the College class. So our modified College.java file is as follows:
A. College Class
Java
package BeanAnnotation;
public class College {
private Principal principal;
public void setPrincipal(Principal principal)
{
this .principal = principal;
}
public void test()
{
principal.principalInfo();
System.out.println( "Test College Method" );
}
}
|
Now come to the CollegeConfig.java file and the modified CollegeConfig.java is given below as follows:
B. Configuration Class
Java
package BeanAnnotation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CollegeConfig {
@Bean public Principal principalBean()
{
return new Principal();
}
@Bean public College collegeBean()
{
College college = new College();
college.setPrincipal(principalBean());
return college;
}
}
|
And finally Below is the code for the Main.java file.
C. Application Class
Java
package BeanAnnotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args)
{
ApplicationContext context
= new AnnotationConfigApplicationContext(
CollegeConfig. class );
College college
= context.getBean( "collegeBean" , College. class );
college.test();
}
}
|
Output:
Hi, I am your principal
Test College Method
Feeling lost in the vast world of Backend Development? It's time for a change! Join our
Java Backend Development - Live Course and embark on an exciting journey to master backend development efficiently and on schedule.
What We Offer:
- Comprehensive Course
- Expert Guidance for Efficient Learning
- Hands-on Experience with Real-world Projects
- Proven Track Record with 100,000+ Successful Geeks
Last Updated :
30 Jun, 2022
Like Article
Save Article