Spring BootSpring Boot Basicsbeginner
Updated:

Essential Spring Boot Annotations, Explained in One Place

5 min read

A grouped tour of the annotations that appear in almost every Spring Boot class, what each one signals to the container, and how they combine.

TL;DR – Quick Answer

Spring Boot annotations are markers you place on classes and methods to tell the container how to treat them. Stereotype annotations like @Component, @Service and @Repository register beans; @RestController and the mapping annotations expose HTTP endpoints; @Autowired injects dependencies; and @SpringBootApplication bootstraps the whole application. Learning what each group signals is the fastest way to read Spring Boot code fluently.

On This Page

Open any Spring Boot class and the first thing you see is annotations stacked above the declarations. To a beginner they look like decoration; to the framework they are instructions. Each one tells the container to register a bean, expose an endpoint, or inject a dependency. This tutorial groups the annotations you meet daily so you can read and write Spring Boot code without reaching for a reference every time.

Annotations are instructions to the container

Nothing in Spring Boot happens by convention over a bare class. A plain class is invisible to the framework until an annotation marks it. @Service says "manage this as a bean". @GetMapping says "route this HTTP path here". @Autowired says "supply this dependency". Learning the annotations is therefore learning the vocabulary you use to talk to the container.

They fall into a few clear groups: application bootstrap, stereotypes that register beans, web annotations that handle HTTP, and injection annotations that wire beans together. We will take them group by group.

The bootstrap annotation

Every Spring Boot application has exactly one class carrying @SpringBootApplication:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

This single annotation is a shorthand for three:

  • @SpringBootConfiguration — marks the class as a source of bean definitions.
  • @EnableAutoConfiguration — triggers auto-configuration based on the classpath.
  • @ComponentScan — discovers your other annotated classes in this package and below.

That last point matters in practice: component scanning starts from the package of your main class, so keep it at the top of your package tree or classes in sibling packages will not be found.

Stereotype annotations that register beans

These four mark a class as a bean discovered by component scanning:

Annotation Intended role Notable extra
@Component Generic managed bean The base for the others
@Service Business-logic layer Purely semantic
@Repository Data-access layer Adds exception translation
@Controller Web layer (returns views) Pairs with view templates

Functionally, @Service and @Component do the same registration. The reason to use the specific one is communication: a reader instantly knows a @Repository is a data-access class. @Repository also earns its keep by translating vendor-specific database exceptions into Spring's consistent DataAccessException hierarchy.

@Service
public class OrderService {
    private final OrderRepository repository;

    public OrderService(OrderRepository repository) { // constructor injection
        this.repository = repository;
    }
}

Pro tip: Reach for the most specific stereotype that fits. Using @Component for everything works, but @Service and @Repository document intent and, in the repository case, add real behaviour. Interviewers notice when a candidate uses them deliberately.

Web annotations for HTTP

The web layer is where annotations get dense. @RestController marks a class whose methods return data directly, and the mapping annotations route requests to methods:

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/orders")
public class OrderController {

    @GetMapping("/{id}")
    public String getOrder(@PathVariable Long id) {
        return "Order " + id;
    }

    @GetMapping
    public String listOrders(@RequestParam(defaultValue = "1") int page) {
        return "Orders page " + page;
    }

    @PostMapping
    public String createOrder(@RequestBody String payload) {
        return "Created: " + payload;
    }
}

Several distinctions here are exam favourites. @RestController equals @Controller plus @ResponseBody, so you do not annotate each method. @PathVariable reads a value from the URL path (/api/orders/42), while @RequestParam reads a query parameter (/api/orders?page=2). @RequestBody deserialises the JSON request body into a Java object. These are the building blocks covered in depth in building a REST API with Spring Boot.

Common mistake: Forgetting @RequestBody on a POST parameter. Without it, Spring tries to bind the object from request parameters instead of the JSON body, and your fields come back null. If a posted object is mysteriously empty, this is the first thing to check.

Injection annotations

Once beans exist, you wire them together. @Autowired is the explicit request for injection, though on a single constructor it is optional:

@Service
public class NotificationService {
    private final EmailClient emailClient;

    // @Autowired optional here — one constructor
    public NotificationService(EmailClient emailClient) {
        this.emailClient = emailClient;
    }
}

When two beans of the same type exist, @Qualifier names the one you want, and @Primary marks a default. The full resolution flow — matching by type, then narrowing by qualifier — is covered in the @Autowired tutorial. The key habit to form now is preferring constructor injection, which keeps dependencies final and testable.

Configuration and bean-definition annotations

Beyond stereotypes, @Configuration classes let you define beans explicitly with @Bean methods — useful for third-party classes you cannot annotate:

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

A @Bean method's return value becomes a managed bean, named after the method. This is the manual counterpart to component scanning: you use stereotypes for your own classes and @Bean for objects you do not own.

Transaction and lifecycle annotations

Two more annotations appear constantly once your app touches a database. @Transactional wraps a method in a database transaction — everything inside either commits together or rolls back together:

@Service
public class TransferService {

    @Transactional
    public void transfer(Long from, Long to, double amount) {
        accounts.debit(from, amount);
        accounts.credit(to, amount); // if this throws, the debit rolls back
    }
}

If the credit throws an exception, Spring rolls the whole method back so the money is never lost. The catch that surprises beginners is that @Transactional works through a proxy, so calling one @Transactional method from another method in the same class does not start a new transaction — the internal call bypasses the proxy. That single fact is a frequent interview trap.

The @PostConstruct and @PreDestroy lifecycle annotations round out the set, marking methods that run after a bean is fully wired and just before it is destroyed. They belong to the bean lifecycle rather than the web layer, but you place them with the same annotation-driven style as everything else.

Meta-annotations: annotations made of annotations

The reason @SpringBootApplication and @RestController work is that Spring supports meta-annotations — annotations composed of other annotations. @RestController is literally defined as @Controller plus @ResponseBody. @SpringBootApplication bundles three annotations into one.

This composition is not just Spring's trick; you can use it too. If several classes always carry the same group of annotations, you can define one custom annotation that combines them and apply that instead. Understanding this explains why decomposing a composite annotation is such a common interview question — it tests whether you know that these convenient single annotations are built from smaller, well-understood parts rather than being opaque keywords.

How they combine in a real class

The power comes from stacking. A controller might carry @RestController and @RequestMapping at the class level, @GetMapping on methods, @PathVariable on parameters, and rely on constructor injection for its service. Each annotation contributes one instruction, and the container assembles them into working behaviour. Reading a Spring Boot class fluently is mostly a matter of recognising which group each annotation belongs to.

Interview relevance

Annotation questions are guaranteed in Spring Boot interviews, and they escalate quickly. Start by being able to decompose @SpringBootApplication into its three parts. Explain the difference between @Controller and @RestController, and between @PathVariable and @RequestParam. Know that the stereotypes are mostly semantic except for @Repository's exception translation. Practise these with the dedicated Spring Boot annotations interview questions, where a smooth, grouped answer marks you out from candidates who memorised a flat list.

Frequently Asked Questions

What does @SpringBootApplication actually do?
It is a composite annotation that combines three others: @SpringBootConfiguration for defining beans, @EnableAutoConfiguration to trigger classpath-based auto-configuration, and @ComponentScan to discover your annotated classes. Placing it on your main class bootstraps the entire application in a single annotation.
What is the difference between @Controller and @RestController?
@Controller is the classic MVC annotation whose methods usually return a view name. @RestController is @Controller plus @ResponseBody, so every method returns data serialised directly into the HTTP response body, typically as JSON. Use @RestController for REST APIs and @Controller when rendering server-side views.
Are @Component, @Service and @Repository technically different?
Functionally they all register a bean through component scanning, so you could use @Component everywhere. The difference is semantic and, for @Repository, practical: @Repository adds exception translation for data access. Using the specific stereotype communicates a class's role and helps tooling and future readers.
Do I always need @Autowired for injection?
No. On a class with a single constructor, Spring injects the dependencies automatically since Spring 4.3, so @Autowired on that constructor is optional. You still use it explicitly for field or setter injection, or to mark one constructor among several as the injection point.
What is the difference between @RequestParam and @PathVariable?
@PathVariable binds a value embedded in the URL path, such as the id in /users/42. @RequestParam binds a query-string parameter, such as page in /users?page=2. You choose based on where the value appears in the request URL.

Want to Build Your Career in Java Full Stack with AI?

Join CodeBegun and train with working industry engineers — Explore the Program

Apply for Demo Class →
Siva Prasad Galaba
Founder, CodeBegun · Staff Engineer

Founder of CodeBegun. 15+ years building Java systems at companies like Crunchyroll. Teaches Java, Spring Boot and system design the way the industry actually works, and mentors students through projects, mock interviews and placement preparation.

Technically reviewed by CodeBegun Technical TeamLast reviewed 15 July 2026 LinkedIn
Chat with us