Spring @Bean Annotation with Example - RameshMF/spring-boot-developers-guide GitHub Wiki
In this article, we will discuss Spring Java Configuration based @Bean annotation with examples.
-
@Bean is a method-level annotation and a direct analog of the XML element. The annotation supports some of the attributes offered by, such as init-method, destroy-method, autowiring and name.
-
You can use the @Bean annotation in a @Configuration-annotated or in a @Component-annotated class.
To declare a bean, simply annotate a method with the @Bean annotation. You use this method to register a bean definition within an ApplicationContext of the type specified as the method’s return value. By default, the bean name will be the same as the method name. The following is a simple example of a @Bean method declaration:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.companyname.projectname.customer.CustomerService;
import com.companyname.projectname.order.OrderService;
@Configuration
public class Application {
@Bean
public CustomerService customerService() {
return new CustomerService();
}
@Bean
public OrderService orderService() {
return new OrderService();
}
}
The preceding configuration is exactly equivalent to the following Spring XML:
<beans>
<bean id="customerService" class="com.companyname.projectname.CustomerService"/>
<bean id="orderService" class="com.companyname.projectname.OrderService"/>
</beans>
Note that the method name and bean name in xml are exactly same.
A @Bean annotated method can have an arbitrary number of parameters describing the dependencies required to build that bean. For instance if our CustomerController requires an CustomerService we can materialize that dependency via a method parameter:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.companyname.projectname.customer.CustomerController;
import com.companyname.projectname.customer.CustomerService;
@Configuration
public class Application {
private CustomerService customerService;
@Bean
public CustomerService customerService() {
customerService = new CustomerService();
return customerService;
}
@Bean
public CustomerController customerController(CustomerService customerService) {
return new CustomerController(customerService);
}
}
The resolution mechanism is pretty much identical to constructor-based dependency injection.
The @Bean annotation supports specifying arbitrary initialization and destruction callback methods, much like Spring XML’s init-method and destroy-method attributes on the bean element:
public class Foo {
public void init() {
// initialization logic via xml config
}
}
public class Bar {
public void cleanup() {
// destruction logic via xml config
}
}
@Configuration
public class AppConfig {
@Bean(initMethod = "init")
public Foo foo() {
return new Foo();
}
@Bean(destroyMethod = "cleanup")
public Bar bar() {
return new Bar();
}
}
You can specify that your beans defined with the @Bean annotation should have a specific scope. You can use any of the standard scopes specified in the Bean Scopes section. The default scope is a singleton, but you can override this with the @Scope annotation:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import com.companyname.projectname.customer.CustomerService;
import com.companyname.projectname.order.OrderService;
@Configuration
public class Application {
@Bean
@Scope("prototype")
public CustomerService customerService() {
return new CustomerService();
}
@Bean
@Scope("prototype")
public OrderService orderService() {
return new OrderService();
}
}
By default, configuration classes use a @Bean method’s name as the name of the resulting bean. This functionality can be overridden, however, with the name attribute.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.companyname.projectname.customer.CustomerService;
import com.companyname.projectname.order.OrderService;
@Configuration
public class Application {
@Bean(name = "cService")
public CustomerService customerService() {
return new CustomerService();
}
@Bean(name = "oService")
public OrderService orderService() {
return new OrderService();
}
}
As discussed in Naming beans, it is sometimes desirable to give a single bean multiple names, otherwise known as bean aliasing. The name attribute of the @Bean annotation accepts a String array for this purpose.
@Configuration
public class AppConfig {
@Bean(name = { "dataSource", "subsystemA-dataSource", "subsystemB-dataSource" })
public DataSource dataSource() {
// instantiate, configure and return DataSource bean...
}
}
When @Bean have dependencies on one another, expressing that dependency is as simple as having one bean method call another:
@Configuration
public class AppConfig {
@Bean
public Foo foo() {
return new Foo(bar());
}
@Bean
public Bar bar() {
return new Bar();
}
}