← Back to Questions
Spring Boot

What is @ControllerAdvice annotation?

Learn What is @ControllerAdvice annotation? with simple explanations, real-time examples, interview tips and practical use cases.

What is @ControllerAdvice Annotation in Spring Boot?

@ControllerAdvice is a special annotation in Spring Boot and Spring MVC used to provide centralized exception handling, global data binding, and shared controller-related logic across the entire application.

It allows developers to apply common functionality globally to multiple controllers without duplicating code.

In simple words, @ControllerAdvice acts like a global controller helper that manages exceptions and common configurations for all controllers.


Why is @ControllerAdvice Used?

In large Spring Boot applications, multiple controllers may contain:

  • Repeated exception handling code
  • Duplicate validation logic
  • Common response handling
  • Shared model attributes

Without centralized management:

  • Code duplication increases
  • Maintenance becomes difficult
  • Error responses become inconsistent
  • Application scalability decreases

@ControllerAdvice solves these problems by allowing global handling from one centralized class.


Main Features of @ControllerAdvice

  • Global exception handling
  • Centralized validation handling
  • Shared model attributes
  • Global data binding configuration
  • Cleaner controller code
  • Reusable logic across controllers

Package of @ControllerAdvice

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

How @ControllerAdvice Works

When an exception or controller-related event occurs:

  1. Spring Boot scans for @ControllerAdvice classes
  2. Matching global methods are identified
  3. The appropriate handler method executes
  4. Response is returned to the client

Most Common Usage of @ControllerAdvice

The most common use of @ControllerAdvice is global exception handling.


Simple Example of @ControllerAdvice

Step 1: Create Custom Exception

public class StudentNotFoundException
        extends RuntimeException {

    public StudentNotFoundException(String message) {
        super(message);
    }
}

Step 2: Create Controller

@RestController
public class StudentController {

    @GetMapping("/student/{id}")
    public String getStudent(@PathVariable int id) {

        if(id != 101) {
            throw new StudentNotFoundException(
                    "Student Not Found"
            );
        }

        return "Student Found";
    }
}

Step 3: Create Global Exception Handler

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(StudentNotFoundException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String handleStudentException(
            StudentNotFoundException ex) {

        return ex.getMessage();
    }
}

Output

Student Not Found

HTTP Status

404 NOT FOUND

How @ControllerAdvice Improves Code Quality

Without @ControllerAdvice, every controller would need its own exception handling:

try {
    // business logic
} catch(Exception ex) {
    // repeated code
}

With @ControllerAdvice:

  • Exception handling is centralized
  • Controllers remain clean
  • Code becomes reusable

Returning JSON Responses with @ControllerAdvice

REST APIs usually return structured JSON error responses.

Error Response Class

public class ErrorResponse {

    private String message;
    private int status;

    public ErrorResponse(String message, int status) {
        this.message = message;
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public int getStatus() {
        return status;
    }
}

Global Exception Handler

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(StudentNotFoundException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ErrorResponse handleException(
            StudentNotFoundException ex) {

        return new ErrorResponse(
                ex.getMessage(),
                404
        );
    }
}

JSON Output

{
   "message": "Student Not Found",
   "status": 404
}

Using @RestControllerAdvice

Spring Boot provides another annotation:

@RestControllerAdvice

It is a combination of:

@ControllerAdvice + @ResponseBody

Example Using @RestControllerAdvice

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ErrorResponse handleException(
            Exception ex) {

        return new ErrorResponse(
                ex.getMessage(),
                500
        );
    }
}

Difference Between @ControllerAdvice and @RestControllerAdvice

Feature @ControllerAdvice @RestControllerAdvice
Main Usage MVC + REST REST APIs
Includes @ResponseBody No Yes
Response Type View or Data JSON/Data Only

Handling Multiple Exceptions

One handler method can manage multiple exception types.

Example

@ExceptionHandler({
        ArithmeticException.class,
        NullPointerException.class
})
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleExceptions(Exception ex) {

    return ex.getMessage();
}

Global Validation Handling Example

@ControllerAdvice can also handle validation errors globally.

Example

@ExceptionHandler(
        MethodArgumentNotValidException.class
)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public String handleValidationException(
        MethodArgumentNotValidException ex) {

    return "Validation Failed";
}

Using @ModelAttribute with @ControllerAdvice

@ControllerAdvice can share common model attributes globally.

Example

@ControllerAdvice
public class GlobalModelHandler {

    @ModelAttribute("appName")
    public String appName() {

        return "Dhanish Empower";
    }
}

Now every controller can access:

${appName}

Using @InitBinder with @ControllerAdvice

@ControllerAdvice can configure global data binding.

Example

@ControllerAdvice
public class GlobalBinderConfig {

    @InitBinder
    public void initBinder(WebDataBinder binder) {

        binder.setDisallowedFields("id");
    }
}

Real-Time Example in E-Commerce Application

Suppose an e-commerce API fetches product details.

If the product does not exist:

@GetMapping("/product/{id}")
public String getProduct(@PathVariable int id) {

    if(id != 1) {
        throw new RuntimeException("Product Not Found");
    }

    return "Product Found";
}

Global Exception Handler

@RestControllerAdvice
public class ProductExceptionHandler {

    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ErrorResponse handleException(
            RuntimeException ex) {

        return new ErrorResponse(
                ex.getMessage(),
                404
        );
    }
}

JSON Output

{
   "message": "Product Not Found",
   "status": 404
}

Advantages of @ControllerAdvice

  • Centralized exception handling
  • Cleaner controller code
  • Reduces duplicate code
  • Improves maintainability
  • Provides consistent API responses
  • Supports validation handling
  • Works well with enterprise applications

Disadvantages of @ControllerAdvice

  • Improper configuration may hide exceptions
  • Large applications may require multiple advice classes
  • Generic handlers may reduce debugging clarity

Best Practices for Using @ControllerAdvice

  • Use custom exception classes
  • Return structured JSON responses
  • Use proper HTTP status codes
  • Log exceptions properly
  • Avoid exposing sensitive server details
  • Use @RestControllerAdvice for REST APIs
  • Keep exception handling organized

Difference Between Local and Global Exception Handling

Feature Local Handling Global Handling
Scope Single Controller Entire Application
Code Duplication High Low
Maintainability Difficult Easy
Best For Small Projects Enterprise Applications

Common Interview Questions on @ControllerAdvice

What is @ControllerAdvice in Spring Boot?

@ControllerAdvice is used for centralized exception handling and shared controller-related configurations across the application.

What is the difference between @ControllerAdvice and @RestControllerAdvice?

@RestControllerAdvice automatically includes @ResponseBody and is mainly used for REST APIs.

Can @ControllerAdvice handle validation errors?

Yes. It can globally handle validation exceptions like MethodArgumentNotValidException.

Why is @ControllerAdvice important?

It improves maintainability, reduces duplicate code, and provides centralized error handling.

Can @ControllerAdvice be used with @ModelAttribute?

Yes. It can globally share model attributes across controllers.


Conclusion

@ControllerAdvice is one of the most important annotations in Spring Boot for building scalable, maintainable, and enterprise-grade applications.

It centralizes exception handling, validation management, shared model attributes, and controller-related logic.

Combined with @ExceptionHandler and @RestControllerAdvice, it becomes a powerful mechanism for creating consistent and professional REST APIs.

Understanding @ControllerAdvice is essential for Spring Boot developers because proper global exception handling is a critical part of modern backend application development.

Why this Spring Boot question is important?

This interview question helps candidates understand real-time backend development concepts, practical problem solving, coding fundamentals, system design basics and production-ready application behavior.

Practice this question carefully for Java backend roles, Spring Boot developer interviews, microservices interviews, company interviews and full-stack developer preparation.

About the Author

Naresh Kumar is a Senior Java Backend Engineer with experience building enterprise applications using Java, Spring Boot, Microservices, Docker, Kubernetes and Cloud technologies.