Mastering Spring @Bean: Declaration, Dependencies, Lifecycle & Scopes
This guide explains how to use Spring's @Bean annotation to declare beans, configure dependencies, control lifecycle callbacks, set custom scopes, assign names, aliases, and descriptions, providing Java code examples that parallel equivalent XML configurations.
Environment
Spring version 5.3.25.
@Bean Annotation Basics
@Bean is a method‑level annotation that directly corresponds to the XML <bean/> element. It supports attributes such as init-method , destroy-method , autowiring , and name . You can place @Bean on methods inside @Configuration or @Component classes.
Declaring a Bean
Annotate a method with @Bean to register a bean definition in the ApplicationContext; the bean type is the method's return type and the default bean name matches the method name.
<code>@Configuration
public class AppConfig {
@Bean
public TransferServiceImpl transferService() {
return new TransferServiceImpl();
}
}
</code>The above Java configuration is equivalent to the following XML:
<code><beans>
<bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>
</code>Both configurations make a bean named transferService of type TransferServiceImpl available in the ApplicationContext.
Bean Dependencies
A @Bean method can declare parameters that the container will resolve as dependencies. For example, if TransferService needs an AccountRepository :
<code>@Configuration
public class AppConfig {
@Bean
public TransferService transferService(AccountRepository accountRepository) {
return new TransferServiceImpl(accountRepository);
}
}
</code>Bean Lifecycle
Beans defined with @Bean support standard lifecycle callbacks, including JSR‑250 annotations @PostConstruct and @PreDestroy . They also honor Spring’s own callbacks if the bean implements InitializingBean , DisposableBean , or Lifecycle , and they can use any of the *Aware interfaces.
You can specify custom init and destroy methods just like the XML init-method and destroy-method attributes:
<code>public class BeanOne {
public void init() {
// initialization logic
}
}
public class BeanTwo {
public void cleanup() {
// destruction logic
}
}
@Configuration
public class AppConfig {
@Bean(initMethod = "init")
public BeanOne beanOne() {
return new BeanOne();
}
@Bean(destroyMethod = "cleanup")
public BeanTwo beanTwo() {
return new BeanTwo();
}
}
</code>If a bean has public close or shutdown methods, Spring will invoke them by default. To disable this behavior, set destroyMethod="" on the @Bean definition.
<code>public class Main {
static class Person {
public void close() { System.out.println("close"); }
public void shutdown() { System.out.println("shutdown"); }
}
@Configuration
static class AppConfig {
// @Bean(destroyMethod = "") disables automatic close/shutdown
@Bean
public Person person() { return new Person(); }
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
context.close();
}
}
</code>Bean Scopes
Use the @Scope annotation to change a bean’s scope. The default is singleton , but you can specify others such as prototype :
<code>@Configuration
public class MyConfiguration {
@Bean
@Scope("prototype")
public Encryptor encryptor() {
// ...
}
}
</code>Spring also supports scoped proxies via the proxyMode attribute of @Scope, allowing beans with narrower scopes (e.g., session) to be injected into singleton beans.
<code>// an HTTP Session‑scoped bean exposed as a proxy
@Bean
@SessionScope
public UserPreferences userPreferences() {
return new UserPreferences();
}
@Bean
public Service userService() {
UserService service = new SimpleUserService();
// reference to the proxied userPreferences bean
service.setUserPreferences(userPreferences());
return service;
}
</code>Custom Bean Naming
By default the method name becomes the bean name, but you can override it with the name attribute:
<code>@Configuration
public class AppConfig {
@Bean("myThing")
public Thing thing() {
return new Thing();
}
}
</code>Bean Aliases
Provide multiple names for a single bean using the name attribute with a string array:
<code>@Configuration
public class AppConfig {
@Bean({"dataSource", "subsystemA-dataSource", "subsystemB-dataSource"})
public DataSource dataSource() {
// instantiate, configure and return DataSource bean...
}
}
</code>Bean Description
Attach a textual description to a bean with @Description, useful for monitoring tools such as JMX:
<code>@Configuration
public class AppConfig {
@Bean
@Description("Provides a basic example of a bean")
public Thing thing() {
return new Thing();
}
}
</code>End of guide.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.