When do we use Stereotype annotations and @Bean annotation in Spring?

Photo by Pablo García Saldaña on Unsplash

In the Spring framework(Annotation driven approach) we can create bean definitions in two ways. Using stereotype annotations and @Bean Annotation.

We can use Stereotype annotations(@component,@service,…etc) only when we have source code. We mentioned this annotation at the class level. But in a few of the scenarios, we don’t have access to modify source code (like while using the third-party libraries) and for a few of the bean definitions, we need to make some customization on bean creation.RestTemplate, DataSource, and JdbcTemplate, etc are spring-provided classes and those are not annotated with stereotype annotations. Like this, we have multiple classes/dependencies in spring and other libraries(RabbitMQ, Mail, Messageconverters). Those are not beans or components by default in the IOC container. In order to achieve spring benefits dependency injection, those should be bean definitions in the IOC container. Then only we will get all the benefits provided by the spring framework.

Spring IOC container auto-detect, classes that are annotated with Stereotype annotations by using @ComponentScan annotation.IOC container will load all classes as bean definitions while application startup.

The IOC container is not able to detect customized beans or third-party libraries. To tell the instances of third-party libraries(like RestTemplate, JdbcTemplate, mail configurations, RabbitMQ configuration, etc) as bean definitions to the IOC container, we have to create instances/beans definition manually and give this instance to the IOC container. We can achieve this by using @Bean annotation. We can add this annotation at the method-level. When the application startup, the IOC container will detect @Configuration annotated classes and load all bean definitions.

I have mentioned a few use cases below.

// RestTemplate configuration
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.setConnectTimeout(Duration.ofMillis(3000))