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 Annotation Overview

  • @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.

Declaring a Bean and Example

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.

Bean dependencies

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.

Bean life cycle methods

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();
        }

}

Specifying bean scope Using the @Scope annotation

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();
	}
}

Customizing bean naming

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();
	}
}

Bean aliasing

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...
        }

}

Injecting inter-bean dependencies

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();
        }
}
⚠️ **GitHub.com Fallback** ⚠️