1. Introduction

In this tutorial, we'll look at the stereotype annotations provided by Spring. In essence, stereotype annotations mark classes as a bean candidate.

2. @Component Annotation

We'll start with the @Component annotation.

Firstly, the @Component annotation is the primary annotation for marking classes as beans:

@Component
public class DepartmentComponent {
}

Here, Spring will register DepartmentComponent as a bean.

3. Other Stereotype Annotations

Spring also provides other stereotype annotations. These annotations also include @Component in their definitions.

Firstly, we can use these components for defining beans instead of the @Component annotation. Secondly, some of these annotations provide additional functionality.

3.1. @Repository Annotation

Firstly, we'll investigate the @Repository annotation.

We generally use the @Repository annotation for repository or Dao classes. When we annotate such a class with @Repository, Spring provides additional exception translation support for persistence operations:

@Repository
public class DepartmentRepository {

    public void save(){
        throw new RuntimeException("Planned exception");
    }
}

Here, Spring creates a bean for DepartmentRepository. For exception translation to work, we should also define a PersistenceExceptionTranslator bean:

@Component
public class SimplePersistenceExceptionTranslationPostProcessor implements PersistenceExceptionTranslator {

    @Nullable
    @Override
    public DataAccessException translateExceptionIfPossible(RuntimeException ex) {
        return new TimeAwareDataAccessException(ex);
    }

   // Implementation details
}

After this setup, all thrown exceptions will be translated.

3.2. @Service Annotation

Secondly, we can use the @Service annotation to define beans. This annotation is especially used for classes in the service layer:

@Service
public class DepartmentService {
}

In contrast to @Repository, Spring doesn't provide any additional functionality for the @Service annotated beans.

3.3. @Controller Annotation

We can also use the @Controller annotation to define beans.

We use the @Controller annotation for handler classes containing web operations. Moreover, Spring scans the @Controller annotated classes and creates request mappings:

@Controller
public class DepartmentController {
    // Request mappings
}

4. Custom Annotations

Next, let's look at how we can create a custom annotation for defining beans.

Firstly, each custom annotation should include a Spring stereotype annotation. For example, @RestController is a combination of the @Controller and @ResponseBody annotations.

Let's create a primary component annotation:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
@Primary
public @interface PrimaryComponent {
}

Here, we have the PrimaryComponent annotation. Note that it is also annotated with @Component and @Primary.

Let's see the usage:

public interface Generator {

    void generate();
}
@PrimaryComponent
public class PrimaryGenerator implements Generator {

    @Override
    public void generate() {
        System.out.println("Advanced generator");
    }
}

Here, Spring registers the PrimaryGenerator as a bean. Moreover, it returns PrimaryGenerator as the primary implementation of the Generator interface - when the target bean defines no qualifier.

5. Summary

In this tutorial, we've looked at the stereotype annotations provided by Spring including @Component, @Repository, and others. We also learned how to create a custom component annotation.

Finally, check out the source code over on Github.