Spring @Bean Annotation with Example

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
// Java Program to Illustrate College Classpackage BeanAnnotation;// Importing required classesimport org.springframework.stereotype.Component;// Annotation@Component("collegeBean")// Classpublic class College {    // Method    public void test()    {        // Print statement        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
// Java Program to Illustrate Configuration Classpackage ComponetAnnotation;// Importing required classesimport org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;// Annotation@Configuration@ComponentScan(basePackages = "BeanAnnotation")// Classpublic 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
// Java Program to Illustrate// Configuration of College Classpackage BeanAnnotation;// Importing required classesimport org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;// Annotation@Configuration// Classpublic class CollegeConfig {    // Creating College class Bean    // using Bean annotation    @Bean    // Here the method name is the    // bean id/bean name    public College collegeBean()    {        // Returns the College class object        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
// Java Program to Illustrate Application Classpackage BeanAnnotation;// Importing required classesimport org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;// Main(Application) Classpublic class Main {    // Main driver method    public static void main(String[] args)    {        // Using AnnotationConfigApplicationContext        // instead of ClassPathXmlApplicationContext        // because we are not using XML Configuration        ApplicationContext context            = new AnnotationConfigApplicationContext(                CollegeConfig.class);        // Getting the bean        College college            = context.getBean("collegeBean", College.class);        // Invoking the method        // inside main() method        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
// Java Program to Illustrate Application Classpackage BeanAnnotation;// Importing required classesimport org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;// Application(Main) classpublic class Main {    // main driver method    public static void main(String[] args)    {        // Using AnnotationConfigApplicationContext        // instead of ClassPathXmlApplicationContext        // because we are not using XML Configuration        ApplicationContext context            = new AnnotationConfigApplicationContext(                CollegeConfig.class);        // Getting the bean        College college = context.getBean("myCollegeBean",                                          College.class);        // Invoking the method        // inside main() method        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
// Java Program to Illustrate Principal Classpackage BeanAnnotation;// Classpublic class Principal {    // Method    public void principalInfo()    {        // Print statement        System.out.println("Hi, I am your principal");    }} | 
And our College.class is something like this
Java
// Java Program to Illustrate College Classpackage BeanAnnotation;// Classpublic class College {    // Class data member    private Principal principal;    // Method    public void test()    {        principal.principalInfo();        // Print statement        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
// Java Program to Illustrate College Classpackage BeanAnnotation;// Classpublic 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
// Java Program to Illustrate Configuration Classpackage BeanAnnotation;// Importing required classesimport org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;// Annotation@Configurationpublic class CollegeConfig {    // Creating the Bean for Principal Class    @Bean public Principal principalBean()    {        return new Principal();    }    @Bean public College collegeBean()    {        // Constructor Injection        return new College(principalBean());    }} | 
And finally Below is the code for the Main.java file.
C. Application Class
Java
// Java Program to Illustrate Application Classpackage BeanAnnotation;// Importing required classesimport org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;// Main classpublic class Main {    // Main driver method    public static void main(String[] args)    {        // Using AnnotationConfigApplicationContext        // instead of ClassPathXmlApplicationContext        // because we are not using XML Configuration        ApplicationContext context            = new AnnotationConfigApplicationContext(                CollegeConfig.class);        // Getting the bean        College college            = context.getBean("collegeBean", College.class);        // Invoking the method        // inside main() method        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
// Java Program to Illustrate College Classpackage BeanAnnotation;// Classpublic class College {    // Class data members    private Principal principal;    // Setter    public void setPrincipal(Principal principal)    {        // this keywords refers to current instance itself        this.principal = principal;    }    // Method    public void test()    {        principal.principalInfo();        // Print statement        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
// Java Program to Illustrate Configuration Classpackage BeanAnnotation;// Importing required classesimport org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;// Annotation@Configuration// Classpublic class CollegeConfig {    // Creating the Bean for Principal Class    @Bean public Principal principalBean()    {        return new Principal();    }    @Bean public College collegeBean()    {        // Setter Injection        College college = new College();        college.setPrincipal(principalBean());        return college;    }} | 
And finally Below is the code for the Main.java file.
C. Application Class
Java
// Java Program to Illustrate Application (Main) Classpackage BeanAnnotation;// Importing required classesimport org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;// Application (Main) classpublic class Main {    // Main driver method    public static void main(String[] args)    {        // Using AnnotationConfigApplicationContext        // instead of ClassPathXmlApplicationContext        // because we are not using XML Configuration        ApplicationContext context            = new AnnotationConfigApplicationContext(                CollegeConfig.class);        // Getting the bean        College college            = context.getBean("collegeBean", College.class);        // Invoking the method        // inside main() method        college.test();    }} | 
Output:
Hi, I am your principal Test College Method
				
					


