Important Spring Boot Annotations: What They Do, Why, and How They Work Behind the Scenes



This content originally appeared on DEV Community and was authored by Jack Pritom Soren

Spring Boot is a powerful framework built on top of Spring that simplifies creating production-ready applications. At its core, Spring Boot heavily relies on annotations to reduce boilerplate code and enable auto-configuration. Understanding these annotations is essential to write clean, efficient, and maintainable Spring Boot applications.

Let’s explore the most important Spring Boot annotations, their purpose, behind-the-scenes working, and when to use them.

1. @SpringBootApplication

Purpose:
This is the main entry point annotation for a Spring Boot application. It enables auto-configuration, component scanning, and configuration.

Behind the Scenes:

  • @SpringBootApplication is a meta-annotation, combining three annotations:

    • @SpringBootConfiguration – marks the class as a configuration class (like @Configuration).
    • @EnableAutoConfiguration – tells Spring Boot to automatically configure beans based on the classpath dependencies.
    • @ComponentScan – scans for Spring components (like @Service, @Repository, @Controller) in the current package and sub-packages.

When to Use:

  • On your main class that contains the public static void main() method to start the Spring Boot application.

Example:

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

2. @RestController

Purpose:
Marks a class as a RESTful controller where methods return JSON/XML directly instead of a view.

Behind the Scenes:

  • Combines @Controller and @ResponseBody.
  • Automatically converts returned objects to JSON or XML using HttpMessageConverters.

When to Use:

  • When building REST APIs where endpoints return data rather than views.

Example:

@RestController
@RequestMapping("/api")
public class UserController {
    @GetMapping("/users")
    public List<User> getUsers() {
        return userService.getAllUsers();
    }
}

3. @Service

Purpose:
Indicates that a class holds business logic and should be managed by Spring’s container.

Behind the Scenes:

  • Spring registers the class as a bean in the application context.
  • Enables dependency injection when used with @Autowired or constructor injection.

When to Use:

  • For classes that implement business logic (services, calculations, or processing data).

Example:

@Service
public class UserService {
    public List<User> getAllUsers() {
        return userRepository.findAll();
    }
}

4. @Repository

Purpose:
Marks a class as a data access layer component, responsible for database operations.

Behind the Scenes:

  • Registers the class as a Spring bean.
  • Translates SQL exceptions into Spring’s DataAccessException.

When to Use:

  • On classes interacting with a database (JPA, JDBC, MongoDB repositories).

Example:

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

5. @Component

Purpose:
Generic annotation to mark any Spring-managed bean.

Behind the Scenes:

  • Detected via component scanning and added to the Spring context.
  • Can be injected anywhere via @Autowired.

When to Use:

  • When the class doesn’t fit specifically as @Service, @Repository, or @Controller.

Example:

@Component
public class EmailSender {
    public void send(String message) {
        // send email
    }
}

6. @Autowired

Purpose:
Enables automatic dependency injection of beans.

Behind the Scenes:

  • Spring searches the application context for a compatible bean type and injects it.
  • Can be used on fields, constructors, or setter methods.

When to Use:

  • When you need Spring to automatically provide a dependency without manually instantiating it.

Example:

@Service
public class OrderService {
    @Autowired
    private PaymentService paymentService;
}

7. @Value

Purpose:
Injects values from application.properties, application.yml, or environment variables.

Behind the Scenes:

  • Spring resolves the placeholder ${property.name} and injects the value at runtime.

When to Use:

  • To access configuration values dynamically.

Example:

@Component
public class AppConfig {
    @Value("${app.name}")
    private String appName;
}

8. @RequestMapping, @GetMapping, @PostMapping

Purpose:
Maps HTTP requests to controller methods.

Behind the Scenes:

  • Spring uses HandlerMapping to route requests to the correct method.
  • @GetMapping and @PostMapping are shorthand for @RequestMapping(method = RequestMethod.GET/POST).

When to Use:

  • To define API endpoints in REST controllers.

Example:

@RestController
@RequestMapping("/products")
public class ProductController {
    @GetMapping("/{id}")
    public Product getProduct(@PathVariable Long id) {
        return productService.getProductById(id);
    }
}

9. @Configuration

Purpose:
Marks a class as a configuration class that contains bean definitions.

Behind the Scenes:

  • Spring processes the class and registers all @Bean methods as Spring-managed beans.

When to Use:

  • When you want to explicitly define beans in Java instead of XML.

Example:

@Configuration
public class AppConfig {
    @Bean
    public ObjectMapper objectMapper() {
        return new ObjectMapper();
    }
}

10. @Bean

Purpose:
Defines a Spring-managed bean explicitly.

Behind the Scenes:

  • Method annotated with @Bean is called once during application startup to create and register a bean in the application context.

When to Use:

  • When you want to create custom beans or third-party objects not annotated with Spring annotations.

Example:

@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}

✅ Conclusion

Spring Boot annotations are the backbone of the framework. They reduce boilerplate code, provide automatic wiring and configuration, and help build clean, maintainable applications. Here’s a quick mental map for usage:

  • Application setup: @SpringBootApplication
  • Controller layer: @RestController, @RequestMapping, @GetMapping
  • Service layer: @Service, @Component
  • Data layer: @Repository
  • Dependency injection: @Autowired, @Value
  • Configuration: @Configuration, @Bean

Understanding what happens behind the scenes helps not only in writing code but also in debugging and designing scalable applications.

Follow me on : Github Linkedin Threads Youtube Channel


This content originally appeared on DEV Community and was authored by Jack Pritom Soren