Bean vs. Component in Spring

@Bean vs @Component in Spring Boot

The key difference between the Spring @Bean and @Component annotations is that the @Bean annotation is used to expose the JavaBeans you write yourself, while the @Component annotation exposes JavaBeans whose source code is maintained by someone else.

At the heart of the Spring framework is its Inversion of Control (IoC) container that manages the lifecycle of your application’s most important Spring Beans. However, the IoC container doesn’t manage every Java component on your classpath. It only manages the lifecycle of the JavaBeans you explicitly ask it to manage.

When do you use Spring’s @Bean annotation?

For example, if you write a JavaBean yourself, you can directly add Spring’s @Bean annotation to your source code. Here we ask Spring’s IoC container to manage the lifecycle of all instances of the Score class.

@Bean
public class Score {
  int wins, losses, ties;
}

When do you use Spring’s @Component annotation?

But what if you wanted Spring’s IoC container to manage a Document object from Swagger’s OpenAPI, or a DataSource component from the JDBC API?

You can’t simply edit code in the JDK and add a @Bean annotation to a class from the standard API. That’s where the @Component annotation comes in.

If you want Spring to manage a JavaBean whose code you don’t control, you create a method that returns an instance of the JavaBean in question and then decorate that method with a @Component annotation. Here’s a simple Spring Boot example that demonstrates exactly that:

@Configuration
public class MyConfig {
  @Component
  public DataSource getMyHikariDataSource() {
    HikariDataSource ds = new HikariDataSource();
    ds.setJdbcUrl("jdbc:h2:mem:roshambo");
    return ds;
  }

  @Component
  public ObjectMapper getMyObjectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    return mapper;
  }
}

In this example, we have used the @Component annotation to tell the Spring IoC container to manage the lifecycle of DataSource and ObjectMapper beans.

These components come from the Jackson and JDBC APIs, so we don’t have the ability to edit the source code. That’s why we can’t directly add a @Bean annotation above the class declarations. However, we can use the @Component annotation, along with the @Configuration annotation placed on the class file itself, to tell Spring to manage these externally provided resources.

@Component instead of @Bean?

The @Component annotation isn’t exclusively for use with external APIs. It’s completely allowable for developers to use the @Component annotation instead of the @Bean annotation to expose the JavaBeans they write themselves.

If we removed the @Bean annotation from the Score class above, we could expose the Score through the IoC container by using the @Component annotation as seen in the code below:

@Configuration
public class MyRoshamboConfig {
  @Component
  public Score getTheScore() {
    return new Score
  }
}

When Should You Use @Component vs @Bean?

In larger Spring Boot projects, I tend to favor @Component over @Bean. Using @Component keeps your configuration centralized, typically in a dedicated configuration file, which helps keep your actual JavaBeans clean and free from framework-specific annotations. This makes your codebase more modular and easier to test or reuse outside of Spring.

For smaller projects or quick prototypes, though, I lean toward using @Bean. It’s simpler, more direct, and perfectly suited for lightweight setups where you don’t need complex configuration. If your goal is to spin up microservices quickly, @Bean can help you move fast with minimal overhead.