What is the difference between @Bean and @Component?
Answer:
@Component (Class-level): Applied to classes to let Spring automatically detect and register them via component scanning. Used for your own custom services, controllers, and repositories.
@Bean (Method-level): Used inside a @Configuration class to explicitly declare and instantiate a bean—frequently used when integrating third-party libraries whose source code you cannot modify with @Component.
Controller
What is the difference between @Controller and @RestController?
Answer:
@Controller: Used for traditional web applications rendering views. Methods typically return a String representing a template name (like Thymeleaf or JSP).
@RestController: Combines @Controller and @ResponseBody. It automatically serializes return values directly into the HTTP response body (as JSON/XML via Jackson) instead of looking for view templates.
Exceptions
What is the difference between @ControllerAdvice and @RestControllerAdvice?
Answer:@RestControllerAdvice is simply @ControllerAdvice plus @ResponseBody. Using @RestControllerAdvice ensures that all methods inside your global exception handler automatically return JSON/XML response bodies without requiring you to put @ResponseBody on every single handler method.
Why is the class named GlobalExceptionHandler? Does the name matter?
Answer: No, the class name does not matter to Spring. You can name it anything you like (e.g., AppExceptionHandler).
How Spring finds it: Spring identifies it purely by the presence of the @ControllerAdvice or @RestControllerAdvice annotation during component scanning. “GlobalExceptionHandler” is just an industry-standard convention.
How does @ExceptionHandler work under the hood? Is it Spring AOP?
Answer:
No, it is not handled by standard Spring AOP aspect interceptors (MethodInterceptor). Instead, Spring MVC relies on a dedicated strategy resolver called ExceptionHandlerExceptionResolver. When an exception bubbles up to the DispatcherServlet, this resolver scans registered @ControllerAdvice beans using reflection to find a matching @ExceptionHandler method, executes it, and maps the result to the HTTP response.
Is it okay to return 400 Bad Request for all validation errors?
Answer:
While 400 Bad Request is standard for client-side formatting issues or missing parameters, returning it for all validation errors is bad practice.
Bean Validation failures (@Valid): Often mapped to 400 Bad Request or 422 Unprocessable Entity (indicating syntax is fine, but semantic rules failed).
Business rule validations (e.g., “Insufficient funds”, “User already exists”): Should return semantic status codes like 409 Conflict or 422 Unprocessable Entity with granular field-level error maps.
How to handle different Validation Exceptions Granularly
Answer:
You can create multiple methods inside your @ControllerAdvice class, mapping them to specific validation exceptions or custom exceptions to return different HTTP status codes and payloads:
Click to expand code snippet
@RestControllerAdvicepublic class GlobalExceptionHandler { // 1. Handle missing request parameters or type mismatches ->> 400 Bad Request @ExceptionHandler(MethodArgumentTypeMismatchException.class) public ResponseEntity<ErrorResponse>> handleTypeMismatch(MethodArgumentTypeMismatchException ex) { ErrorResponse error = new ErrorResponse("INVALID_PARAMETER_TYPE", "Parameter '" + ex.getName() + "' has invalid format."); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error); } // 2. Handle resource not found during validation lookup ->> 404 Not Found @ExceptionHandler(ResourceNotFoundException.class) public ResponseEntity<ErrorResponse>> handleNotFound(ResourceNotFoundException ex) { ErrorResponse error = new ErrorResponse("RESOURCE_NOT_FOUND", ex.getMessage()); return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error); } // 3. Handle general @Valid Bean validation failures ->> 422 Unprocessable Entity (or 400) @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<Map<String, String>>>> handleValidationErrors(MethodArgumentNotValidException ex) { Map<String, String>> errors = new HashMap<>>(); ex.getBindingResult().getFieldErrors().forEach(error ->> errors.put(error.getField(), error.getDefaultMessage()) ); // You can choose 400, or 422 Unprocessable Entity depending on API design standards return ResponseEntity.status(HttpStatus.UNPROCESSABLE_ENTITY).body(errors); }}
Interview Pro-Tip
When asked about validation handling, explain that separating validation errors allows API consumers to parse specific field-level error maps, whereas business logic violations (like “Insufficient Funds”) should return a distinct status like 422 Unprocessable Entity or 409 Conflict instead of a generic 400 Bad Request.
Transactions
What happens if you call a @Transactional method from another method inside the same class?
Answer:
It bypasses the Spring proxy entirely, and the transaction configuration is ignored. Spring creates transactions via dynamic proxies wrapping your bean. When you call this.methodB() internally from inside the same class, you are invoking it directly on the raw object instance, bypassing the proxy interceptor entirely.
By default, what types of exceptions trigger a transaction rollback in Spring @Transactional?
Answer:
By default, Spring only rolls back transactions on Unchecked Exceptions (RuntimeException and its subclasses, including NullPointerException, IllegalArgumentException, etc.) and Error.
Checked Exceptions (like IOException or custom checked exceptions) do not trigger a rollback by default unless explicitly configured using rollbackFor = Exception.class.
Explain Transaction Propagation: What is the difference between REQUIRED and REQUIRES_NEW?
Answer:
REQUIRED (Default): If a transaction already exists, the current method joins it. If no transaction exists, a new one is created.
REQUIRES_NEW: Suspends any existing transaction and creates a brand-new, completely independent physical transaction. If the inner transaction fails and rolls back, it does not force a rollback of the outer transaction unless the outer transaction catches and handles that exception incorrectly.