You know, @Bean is a very commonly used annotation in Spring framework. It’s a method-level annotation, which indicates that the annotated method produces a bean to be managed by the Spring container. A Spring bean is a Java object managed by Spring’s IoC (Inversion of Control) container and it can be used by other objects via dependency injection.

NOTE: This article is not about Spring beans in general, it’s about how to use the @Bean annotation itself.

Let’s see the first example. Given the following Java class:

package net.codejava.bean;

public class Foo {
	
	public void doFooStuff() {
		System.out.println("I'm doing something useful...");
	}
}
We want to have an object of this class available to be used by other objects in the application, so we declare a bean of type Foo in a Spring configuration class as follows:

package net.codejava.bean;

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

@Configuration
public class AppConfig {

	@Bean
	public Foo myBean() {
		return new Foo();
	}	
}
Here, when the Spring container found the myBean() method annotated with @Bean annotation, it will put the object produced by this method into the application context or IoC container, with the name “myBean” which is name of the method itself. Once managed, this bean can be used by other object via dependency injection. For example:

package net.codejava.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class FooService {

	@Autowired Foo foo;
	
	public void doFooService() {
		foo.doFooStuff();
	}
}
Here, the field foo is annotated with @Autowired annotation - meaning that Spring will find an available bean of the same type in the IoC container and then inject it into the object of type FooService. That’s a typical example of declaring a bean and how to use it in a Spring application.

You can get a bean directly from the application context, as shown in the following example:

package net.codejava;

import org.springframework.beans.BeansException;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import net.codejava.bean.Foo;

@SpringBootApplication
public class SpringAnnotationsApplication implements ApplicationContextAware {

	static ApplicationContext context;

	public static void main(String[] args) {
		SpringApplication.run(SpringAnnotationsApplication.class, args);
		
		Foo foo = (Foo) context.getBean("myBean");
		foo.doFooStuff();		
	}

	@Override
	public void setApplicationContext(ApplicationContext context) throws BeansException {
		this.context = context;
	}

}
This is the main class of a Spring Boot application. Upon startup, it will find a bean with name “myBean” in the application context, and then invoke its method doFooStuff().

You can also declare more than one beans in a configuration class, as shown in the following example:

package net.codejava.bean;

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

@Configuration
public class AppConfig {

	@Bean
	public Foo fooBean() {
		return new Foo();
	}
	
	@Bean
	public Bar barBean() {
		return new Bar();
	}
}


Here, the first bean of type Foo has the name “fooBean”, and the second one of type Bar has the name “barBean” - as by convention, the method name also specifies the bean name.

The @Bean annotation has 4 optional elements (parameters) as described below:

  • autowireCandidate: a boolean value indicates the bean can be autowired or not. Default is true.
  • destroyMethod: a String specifies optional name of a method to call on the bean instance upon closing the application context. The default name is “close” or “shutdown”.
  • initMethod: a String specifies optional name of a method to call on the bean instance during initialization. The default value is “”, indicating no method to be called.
  • name: an array of String specifies one or more names for the bean. If left unspecified, the name of the bean is the name of the annotated method. If specified, the method name is ignored.
Let’s see some examples that illustrate using these optional elements of the @Bean annotation. The following example shows two beans are specified multiple names:

@Bean({"foo", "fooBean", "myBean"})
public Foo myBean() {
	return new Foo();
}


@Bean(name = {"bar", "BAR", "Bar"})
public Bar barBean() {
	return new Bar();
}
The following example shows a bean is declared with attribute autowireCandidate is false:

@Bean(autowireCandidate = false)
public Foo myBean() {
	return new Foo();
}
That means the following autowire won’t work - but the bean is still accessible via application context:

@Service
public class FooService {

	@Autowired Foo foo;
	
	public void doFooService() {
		foo.doFooStuff();
	}
}
The following example shows how to specify names of the init and destroy methods to call:

@Bean(initMethod = "initBar", destroyMethod = "closeBar")
public Bar barBean() {
	return new Bar();
}
And code of the bean class is as follows:

package net.codejava.bean;

public class Bar {

	public void initBar() {
		System.out.println("Initializing bar stuffs...");
	}
	
	public void doBarStuff() {
		System.out.println("Doing bar stuffs...");
	}
	
	public void closeBar() {
		System.out.println("Closing bar stuffs...");
	}
}
And finally, let me show you a real world example that declares some beans used by Spring Security, as shown below:

@Configuration
public class WebSecurityConfig {
	
    @Bean
    public UserDetailsService userDetailsService() {
        return new CustomUserDetailsService();
    }
    
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
 	// ...
 	
        return http.build();
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        // ...
    }
}
Those are various code examples that help you understand the meaning of @Bean annotation and how to use it in Spring application. I hope you find my explanation and code examples helpful. To learn more, check the resources in the Reference section below.

You can also watch the video below to see the coding using Spring @Bean annotation in action:

 

Reference:

Bean Overview - Spring Framework docs

@Bean - Spring Java Config

Annotation Interface Bean - Spring Javadocs


About the Author:

is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.



Add comment