The org.springframework.stereotype package contains annotations that mark a class's role within a Spring application: @Component, @Controller, @Service, and @Repository.
You already met @Component in the previous topic — it's the general-purpose stereotype that makes a class eligible for automatic detection and injection by Spring. @Controller, @Service, and @Repository are all specialized versions of @Component, so everything you learned there (auto-detection, constructor injection, singleton by default) still applies to them.
This topic takes a close look at the three specialized stereotypes — what each one communicates about a class's role, and when to use one instead of plain @Component.
@Controller annotation
The @Controller annotation operates like a bouncer at a club. It checks if a request is legit before letting it into the club (the application). If the request fails the validation, the bouncer (the controller) turns it away.
To put things in professional terms - the @Controller annotation in Spring Boot marks a class as a controller managing HTTP requests.
Example:
Java
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.ResponseBody
@Controller
public class MyController {
@GetMapping("/hello")
@ResponseBody
public String helloWorld() {
return "Hello, World!";
}
// Other methods...
}Kotlin
import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.ResponseBody
@Controller
class MyController {
@GetMapping("/hello")
@ResponseBody
fun helloWorld(): String {
return "Hello, World!"
}
// Other methods...
}In this example, the method helloWorld(); is an HTTP response to a GET request, returning the response body: Hello, World!. For illustration, let's assume this is your website - https://my-site.com/. Following the link https://my-site.com/home will display "Hello, World!" on the page.
The methods and business logic can change based on your needs.
You might wonder about the difference between @Controller and @Component or ask yourself whether you can use the second option instead of the first.
@Controllerand@Component, as discussed, are annotations symbolizing classes usable in web applications. Both inherit from the@Componentannotation, which is common to all Spring Framework components performing similar roles but serve distinct purposes.@Controllersignals that the class is meant to handle HTTP requests. This means classes bearing the@Controllerannotation usually have methods matching HTTP methods like GET, POST, PUT, and DELETE.On the other hand,
@Componentdoes not enforce any predetermined utilization conventions on the class. It would be advisable to pragmatically apply the@Componentannotation, so respond to the question "can@Componentbe used instead of@Controller" with an understanding of the difference between "can be used" and "correctly used".
@Service annotation
The @Service annotation in Spring Boot marks a class as a service that executes the application's business logic. By tagging a class with the @Service annotation, Spring will automatically generate that class's instance and include it in its container as a bean.
Services can communicate with other parts of the application, such as repositories and other services, to send, process, and receive data. The @Service annotation helps you organize your code better and simplifies testing since you can conveniently replace real services with mock objects during unit testing.
A solid example of using the @Service annotation would be the following code:
Example:
Java
import org.springframework.stereotype.Service
@Service
public class MyService {
private String generatePasswordHash(String userPassword) {
// Implementing Password Hash Generation
// ...
return hashedPassword
}
}Kotlin
import org.springframework.stereotype.Service
@Service
class MyService {
private fun generatePasswordHash(userPassword: String): String {
// Implementing Password Hash Generation
// ...
return hashedPassword
}
}In this example, the MyService class is a business logic class responsible for hashing the user's password during registration or authorization or for other requirements.
By now, you've probably noticed the similarity in functionality between @Service and @Component in the Spring Framework. As with @Controller, the 'What's the difference? And can I use @Component instead of @Service?' question is relevant.
The answer again lies in semantics. The @Service annotation is part of the aforementioned list of specialized annotations.
If a class executes business logic or represents a service, we recommend using
@Servicebecause it more clearly explains the class's purpose. However, if you have a class that is neither a service nor has specific business logic,@Componentmight be a suitable option. In most cases, you can use@Serviceand@Componentinterchangeably. Although you can use@Componentinstead of@Service, the choice depends on your preference and your intention to explicitly convey your code's semantics.
@Repository annotation
The @Repository annotation, a specialized version of @Component, marks classes as repositories for data access. Developers frequently use this to label classes that interact with a database. Along with delivering specific semantics about exception handling related to data access, @Repository catches DataAccessException exceptions and translates them into more informative Spring exceptions.
Example:
Java
import org.springframework.stereotype.Repository
@Repository
public class MyRepository {
public void save(MyEntity entity) {
// Implementing Persistence
// ...
}
public MyEntity findById(Long id) {
// Implementing ID Search
// ...
}
}Kotlin
import org.springframework.stereotype.Repository
@Repository
class MyRepository {
fun save(entity: MyEntity) {
// Implementing Persistence
// ...
}
fun findById(id: Long): MyEntity? {
// Implementing ID Search
// ...
}
}For instance, in the above example, the MyRepository class carries the @Repository annotation. This tells the Spring Framework that the MyRepository class will handle data store interactions for MyEntity objects.
When considering whether you can use @Component instead of @Repository in this context, it will indeed be less informative from the standpoint of the semantics of your code. To show that a class is a data repository, using @Repository improves your code's readability, especially in large applications. Therefore, it's best to use @Repository for data access repositories.
Conclusion
@Controller, @Service, and @Repository are all specialized versions of @Component, each signaling a specific role: handling HTTP requests, executing business logic, or accessing data (with the added benefit of exception translation for @Repository). Using the specific stereotype instead of plain @Component makes your code's intent clearer at a glance, especially in larger applications — reserve @Component for classes that genuinely don't fit any of the three specialized roles.