1. Overview

In this tutorial, we'll take a comprehensive look at the Spring @Component annotation and related areas. We'll see the different ways we can use it to integrate with some core Spring functionality and how to take advantage of its many benefits.

Further reading:

Spring Core Annotations

Explore the most commonly used Spring core annotations.

Spring Bean Annotations

Learn how and when to use the standard Spring bean annotations - @Component, @Repository, @Service and @Controller.

Spring Web Annotations

Explore the main annotations you can use to handle HTTP requests and responses in Spring MVC.

2. Spring ApplicationContext

Before we can understand the value of @Component, we first need to understand a little bit about the Spring ApplicationContext.

Spring ApplicationContext is where Spring holds instances of objects that it has identified to be managed and distributed automatically. These are called beans.

Bean management and the opportunity for dependency injection are some of Spring's main features.

Using the Inversion of Control principle, Spring collects bean instances from our application and uses them at the appropriate time. We can show bean dependencies to Spring without needing to handle the setup and instantiation of those objects.

The ability to use annotations like @Autowired to inject Spring-managed beans into our application is a driving force for creating powerful and scalable code in Spring.

So, how do we tell Spring about the beans we want it to manage for us? We should take advantage of Spring's automatic bean detection by using stereotype annotations on our classes.

3. @Component

@Component is an annotation that allows Spring to automatically detect our custom beans.

In other words, without having to write any explicit code, Spring will:

  • Scan our application for classes annotated with @Component
  • Instantiate them and inject any specified dependencies into them
  • Inject them wherever needed

However, most developers prefer to use the more specialized stereotype annotations to serve this function.

3.1. Spring Stereotype Annotations

Spring has provided a few specialized stereotype annotations: @Controller, @Service and @Repository. They all provide the same function as @Component.

They all act the same because they are all composed annotations with @Component as a meta-annotation for each of them. They are like @Component aliases with specialized uses and meaning outside of Spring auto-detection or dependency injection.

If we really wanted to, we could theoretically choose to use @Component exclusively for our bean auto-detection needs. On the flip side, we could also compose our own specialized annotations that use @Component.

However, there are other areas of Spring that look specifically for Spring's specialized annotations to provide additional automation benefits. So, we should probably just stick with using the established specializations most of the time.

Let's assume we have an example of each of these cases in our Spring Boot project:

public class ControllerExample {

public class ServiceExample {

public class RepositoryExample {

public class ComponentExample {

public @interface CustomComponent {

public class CustomComponentExample {

We could write a test that proves that each one is auto-detected by Spring and added to the ApplicationContext:

public class ComponentUnitTest {

    private ApplicationContext applicationContext;

    public void givenInScopeComponents_whenSearchingInApplicationContext_thenFindThem() {

3.2. @ComponentScan

Before we rely completely on @Component, we must understand that it's only a plain annotation. The annotation serves the purpose of differentiating beans from other objects, such as domain objects.

However, Spring uses the @ComponentScan annotation to actually gather them all into its ApplicationContext.

If we're writing a Spring Boot application, it is helpful to know that @SpringBootApplication is a composed annotation that includes @ComponentScan. As long as our @SpringBootApplication class is at the root of our project, it will scan every @Component we define by default.

But in case our @SpringBootApplication class can't be at the root of our project or we want to scan outside sources, we can configure @ComponentScan explicitly to look in whatever package we specify, as long as it exists on the classpath.

Let's define an out-of-scope @Component bean:

package com.baeldung.component.scannedscope;

public class ScannedScopeExample {

Next, we can include it via explicit instructions to our @ComponentScan annotation:

package com.baeldung.component.inscope;

@ComponentScan({"com.baeldung.component.inscope", "com.baeldung.component.scannedscope"})
public class ComponentApplication {
    //public static void main(String[] args) {...}

Finally, we can test that it exists:

public void givenScannedScopeComponent_whenSearchingInApplicationContext_thenFindIt() {

In reality, this is more likely to happen when we want to scan for an outside dependency that is included in our project.

3.3. @Component Limitations

There are some scenarios where we want a certain object to become a Spring-managed bean when we can't use @Component.

Let's define an object annotated with @Component in a package outside of our project:

package com.baeldung.component.outsidescope;

public class OutsideScopeExample {

Here is a test that proves that the ApplicationContext does not include the outside component:

public void givenOutsideScopeComponent_whenSearchingInApplicationContext_thenFail() {
    assertThrows(NoSuchBeanDefinitionException.class, () -> applicationContext.getBean(OutsideScopeExample.class));

Also, we may not have access to the source code because it comes from a third-party source, and we're unable to add the @Component annotation. Or perhaps we want to conditionally use one bean implementation over another depending on the environment we're running in. Auto-detection is sufficient most of the time, but when it's not, we can use @Bean.

4. @Component vs @Bean

@Bean is also an annotation that Spring uses to gather beans at runtime, but it's not used at the class level. Instead, we annotate methods with @Bean so that Spring can store the method's result as a Spring bean.

We'll first create a POJO that has no annotations:

public class BeanExample {

Inside of our class annotated with @Configuration, we can create a bean generating method:

public BeanExample beanExample() {
    return new BeanExample();

BeanExample might represent a local class, or it might be an external class. It doesn't matter because we simply need to return an instance of it.

We can then write a test that verifies Spring did pick up the bean:

public void givenBeanComponents_whenSearchingInApplicationContext_thenFindThem() {

There are some important implications we should note because of the differences between @Component and @Bean.

  • @Component is a class-level annotation, but @Bean is at the method level, so @Component is only an option when a class's source code is editable. @Bean can always be used, but it's more verbose.
  • @Component is compatible with Spring's auto-detection, but @Bean requires manual class instantiation.
  • Using @Bean decouples the instantiation of the bean from its class definition. This is why we can use it to make even third-party classes into Spring beans. It also means we can introduce logic to decide which of several possible instance options for a bean to use.

5. Conclusion

We've just explored the Spring @Component annotation as well as other relevant topics. First, we discussed the various Spring stereotype annotations, which are just specialized versions of @Component.

Then we learned that @Component doesn't do anything unless it can be found by @ComponentScan.

Finally, since it's not possible to use @Component on classes that we don't have the source code for, we learned how to use the @Bean annotation instead.

All of these code examples and more can be found over on GitHub.

Spring bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

Generic footer banner
Comments are closed on this article!