Skip to main content

Part 2: Spring Framework Mastery

· 4 min read

Section 1: Dependency Injection (DI)

Q1: What is Dependency Injection and why is it important? Answer: DI decouples object creation from usage. It promotes loose coupling, easier testing, and maintainability. Spring supports:

  • Constructor injection: Preferred for mandatory dependencies.
  • Setter injection: Optional dependencies.
  • Field injection: Quick, but harder to test.

Example:

@Service
public class OrderService {
private final PaymentService paymentService;

@Autowired
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}

Tip: Always explain trade-offs and testing implications.

Q2: Difference between @Component, @Service, @Repository, @Controller?

  • @Component: Generic stereotype.
  • @Service: Business logic layer.
  • @Repository: Data access, converts SQL exceptions to Spring exceptions.
  • @Controller: Presentation layer for MVC web apps.

Q3: Bean scopes in Spring?

  • Singleton: One instance per container (default).
  • Prototype: New instance each injection.
  • Request: Per HTTP request.
  • Session: Per HTTP session.
  • Application: Global per ServletContext.

Q4: Lazy vs Eager initialization?

  • Eager: Instantiated at startup.
  • Lazy: Instantiated when first requested. Useful for optimizing startup time.

Section 2: Spring Bean Lifecycle

Q5: How does Spring manage bean lifecycle?

  • Instantiation → Dependency Injection → Post-construct initialization → Ready → Pre-destroy → Destruction.
  • Key interfaces: InitializingBean, DisposableBean, BeanPostProcessor, @PostConstruct, @PreDestroy.

Q6: Explain circular dependency resolution in Spring.

  • Spring can resolve circular dependencies for singleton beans via setter injection but not with constructor injection.
  • Real-world scenario: Two services referencing each other must use setter injection to avoid BeanCurrentlyInCreationException.

Section 3: Aspect-Oriented Programming (AOP)

Q7: What is AOP and why is it used?

  • Separates cross-cutting concerns like logging, security, and transactions.
  • Key annotations: @Aspect, @Before, @After, @Around, @AfterReturning, @AfterThrowing.

Q8: Example: Logging method execution time

@Aspect
@Component
public class LoggingAspect {
@Around("@annotation(LogExecutionTime)")
public Object logTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
System.out.println("Execution time: " + (System.currentTimeMillis() - start) + "ms");
return result;
}
}

Tip: In interviews, explain proxy-based implementation (JDK vs CGLIB).

Q9: Difference between @Aspect and BeanPostProcessor

  • AOP: Dynamic proxies for method interception.
  • BeanPostProcessor: Hook into bean initialization lifecycle. Both can handle cross-cutting logic, but use-case differs.

Section 4: Spring MVC

Q10: Explain Spring MVC architecture.

  • DispatcherServlet → Controllers → Services → Repositories → View Resolver.
  • Handles request mapping, validation, and response rendering.

Q11: Difference between @Controller and @RestController

  • @Controller: Returns view names, requires @ResponseBody for JSON.
  • @RestController: Implicitly adds @ResponseBody, used for REST APIs.

Q12: How does Spring handle form validation?

  • Use @Valid or @Validated on request objects with JSR-303 annotations like @NotNull, @Size.
  • Example:
@PostMapping("/create")
public ResponseEntity<?> createUser(@Valid @RequestBody UserDto user, BindingResult result) {
if(result.hasErrors()) return ResponseEntity.badRequest().body(result.getAllErrors());
return ResponseEntity.ok(userService.create(user));
}

Q13: Explain path variables and request params.

@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id, @RequestParam(required=false) String filter) { }

Q14: Exception handling in Spring MVC

  • Use @ControllerAdvice with @ExceptionHandler to centralize exception handling.

Section 5: Spring Data JPA

Q15: What is Spring Data JPA?

  • Simplifies repository layer using JpaRepository or CrudRepository.
  • Provides methods like save(), findAll(), deleteById() automatically.

Q16: Custom queries using @Query

@Query("SELECT u FROM User u WHERE u.age > :age")
List<User> findUsersOlderThan(@Param("age") int age);

Q17: Transaction management

  • Use @Transactional. Key attributes: propagation, isolation, readOnly.
  • Pitfall: Avoid transactional methods calling private methods (self-invocation bypasses proxy).

Q18: Difference between save() and saveAndFlush()

  • save(): Persist entity, may delay flush.
  • saveAndFlush(): Immediately flush to DB.

Q19: Lazy vs Eager fetching

  • Lazy: Loaded on demand, avoids unnecessary queries.
  • Eager: Loaded immediately, may lead to performance issues.
  • Interview Tip: Explain N+1 problem and solution with @EntityGraph.

Section 6: Spring Security

Q20: How does Spring Security work?

  • Filters authenticate requests, authorize based on roles, secure endpoints, support OAuth2/JWT.
  • Core components: AuthenticationManager, UserDetailsService, PasswordEncoder.

Q21: Example: Securing REST APIs with JWT

  • Authenticate → generate JWT → send to client → validate JWT in filter for each request.

Q22: Password encoding

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

Q23: Role-based vs Method-level security

  • @PreAuthorize("hasRole('ADMIN')") for method-level access control.
  • Pitfall: Always encode passwords, avoid storing plain text.

Section 7: Event-Driven Design in Spring

Q24: How does Spring handle events?

  • Use ApplicationEventPublisher and @EventListener.
  • Example:
@Component
public class OrderPublisher {
@Autowired ApplicationEventPublisher publisher;
public void publish(Order order) {
publisher.publishEvent(new OrderCreatedEvent(this, order));
}
}
@Component
public class OrderListener {
@EventListener
public void handle(OrderCreatedEvent event) { /* send notification */ }
}

Q25: Asynchronous events

  • Annotate listener with @Async and configure TaskExecutor for non-blocking processing.

Q26: Difference between synchronous and asynchronous events

  • Synchronous: Listener executes in same thread.
  • Asynchronous: Executes in separate thread, better for decoupling and performance.

Section 8: Spring Best Practices & Pitfalls

  1. Prefer constructor injection over field injection.
  2. Avoid circular dependencies; use setter injection or @Lazy.
  3. Keep services stateless for thread safety.
  4. Use @Transactional carefully; understand propagation and rollback rules.
  5. Always handle exceptions centrally with @ControllerAdvice.
  6. Avoid eager loading large associations in entities; prefer DTOs or projections.