Spring - Stereotype Annotations

Spring provides several stereotype annotations that mark classes as Spring-managed beans. Component scanning automatically detects these annotations and registers the classes as beans in the ApplicationContext: no XML bean definitions needed.

Contents

@Component

@Component is the generic stereotype annotation. Any class annotated with it is registered as a bean during component scanning. @Service, @Repository, and @Controller are all specialisations of @Component.

Java
import org.springframework.stereotype.Component;

@Component
public class PdfGenerator {

    public byte[] generate(String content) {
        // PDF generation logic
        return new byte[0];
    }
}

@Service

@Service is used for classes that hold business logic. It is semantically more expressive than @Component and signals the role of the class in the application.

Java
import org.springframework.stereotype.Service;

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User findById(Long id) {
        return userRepository.findById(id)
               .orElseThrow(() -> new UserNotFoundException(id));
    }
}

@Repository

@Repository marks the data access layer. In addition to bean registration, Spring translates low-level data-access exceptions (e.g., SQLException) into Spring's DataAccessException hierarchy.

Java
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@Repository
public class InMemoryProductRepository {

    private final Map<Long, Product> store = new HashMap<>();

    public void save(Product product) {
        store.put(product.getId(), product);
    }

    public Optional<Product> findById(Long id) {
        return Optional.ofNullable(store.get(id));
    }
}

@Controller

@Controller marks a class as a Spring MVC controller. Methods inside it are mapped to HTTP request URLs.

Java
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {

    @GetMapping("/")
    public String home() {
        return "home";   // returns view name resolved by ViewResolver
    }
}

@Autowired and @Qualifier

@Autowired injects a matching bean from the ApplicationContext. When multiple beans of the same type exist, use @Qualifier to pick the right one by bean name.

Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class PaymentService {

    private final PaymentGateway gateway;

    @Autowired
    public PaymentService(@Qualifier("stripeGateway") PaymentGateway gateway) {
        this.gateway = gateway;
    }
}

Enabling Component Scanning

In a Spring Boot application component scanning is enabled automatically via @SpringBootApplication. In a plain Spring app, add @ComponentScan to the configuration class.

Java
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "io.cscode.spring")
public class AppConfig {
    // All @Component, @Service, @Repository and @Controller classes
    // under io.cscode.spring are registered automatically.
}