@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.
import org.springframework.stereotype.Component;
@Component
public class PdfGenerator {
public byte[] generate(String content) {
// PDF generation logic
return new byte[0];
}
}
@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.
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 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.
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 marks a class as a Spring MVC controller. Methods inside it are mapped to HTTP request URLs.
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 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.
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;
}
}
In a Spring Boot application component scanning is enabled automatically via @SpringBootApplication. In a plain Spring app, add @ComponentScan to the configuration class.
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.
}