The key difference between the Spring @Component and @Bean annotations is that the @Bean annotation can be used to expose JavaBeans you write yourself, while the @Component annotation can be used to expose 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 JavaBeans. However, the IoC container doesn’t manage every JavaBean your application might need. It only manages the lifecycle of the JavaBeans you explicitly ask it to manage.
When do you use Spring’s @Bean annotation?
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.
@Beanpublicclass Score {
int wins, losses, ties;
}
When do you use Spring’s @Component annotation?
But what if you wanted Spring’s IoC container to manage an ObjectMapper from the Jackson API, 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, as in the following example:
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:
On Spring Boot projects of any significant size, I actually prefer to use @Component annotations instead of @Bean annotations. That way, configuration is confined to a single file, while the JavaBeans you write are not littered with annotations that tightly bind your source code to the Spring framework.
On smaller projects and prototypes? I’m all in with the @Bean annotation. It’s easier to use and if your project doesn’t require extensive configuration, it can help you get your microservices up and running faster.