Spring — Cheat Sheet

Tags: spring, spring-boot, java, dependency-injection, ioc, aop, rest, bean

Level: intermediate

TL;DR: Core enterprise Java framework managing component lifecycle via IoC/DI, providing declarative services through AOP, and standardizing REST APIs.

Key concepts

Inversion of Control delegates object creation and dependency management to the Spring IoC container.

Dependency Injection injects collaborators via constructor, setter, or field injection.

Constructor injection is the recommended approach to ensure immutability and ease unit testing.

Spring beans are managed objects configured via annotations like @Component, @Service, or @Bean.

Default bean scope is singleton; alternate scopes include prototype, request, session, and application.

ApplicationContext is the primary container interface extending BeanFactory with enterprise features.

Aspect-Oriented Programming decouples cross-cutting concerns like transactions, logging, and security.

Spring Boot provides opinionated auto-configuration, standalone executable JARs, and production-ready actuators.

DispatcherServlet handles incoming HTTP traffic and routes requests through handler mappings to controllers.

Spring Data simplifies data persistence through repository abstractions and auto-generated queries.

Typical questions and ready answers

Q: What is the difference between BeanFactory and ApplicationContext?R: BeanFactory provides basic IoC and lazy bean loading. ApplicationContext is a superset that pre-instantiates singletons and adds AOP integration, events, and message source resolution.

Q: Why should constructor injection be preferred over field injection?R: Constructor injection prevents NullPointerException by guaranteeing dependencies exist at instantiation, makes beans immutable, and avoids hidden coupling during unit testing.

Q: How does Spring manage transactions with @Transactional?R: Spring wraps the bean in an AOP proxy that intercepts calls, starts or joins a transaction before execution, and handles commit or rollback on exceptions.

Q: What happens if a @Transactional method is called from another method within the same class?R: The call bypasses the Spring proxy, invoking the internal target directly, which prevents the transaction interceptor from executing.

Pitfalls and common mistakes

Calling an annotated @Transactional or @Async method internally on this bypasses the AOP proxy.

Using field injection with @Autowired complicates pure unit testing without reflection or Spring context.

Modifying mutable state inside singleton beans creates concurrency issues under multi-threaded requests.

Catching checked exceptions inside a @Transactional method without rethrowing causes unexpected commit instead of rollback.

Neglecting circular dependencies between beans when constructor injection is applied without @Lazy or refactoring.

Snippets and commands

// Immutable service with constructor injection and declarative transaction
@Service
public class OrderService {

    private final OrderRepository orderRepository;
    private final PaymentClient paymentClient;

    public OrderService(OrderRepository orderRepository, PaymentClient paymentClient) {
        this.orderRepository = orderRepository;
        this.paymentClient = paymentClient;
    }

    @Transactional
    public Order processOrder(OrderRequest request) {
        Order order = new Order(request);
        paymentClient.charge(order.getTotal());
        return orderRepository.save(order);
    }
}

Java

// REST Controller exposing standard JSON endpoints
@RestController
@RequestMapping("/api/orders")
public class OrderController {

    private final OrderService orderService;

    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }

    @PostMapping
    public ResponseEntity<Order> create(@Valid @RequestBody OrderRequest request) {
        Order created = orderService.processOrder(request);
        return ResponseEntity.status(HttpStatus.CREATED).body(created);
    }
}

To review

[ ] Bean lifecycle stages from BeanNameAware to InitializingBean and DisposableBean

[ ] Proxy mechanisms: dynamic JDK reflection proxies versus CGLIB subclassing

[ ] Transaction propagation modes (REQUIRED, REQUIRES_NEW, NESTED)

[ ] Auto-configuration triggers in Spring Boot using @ConditionalOnClass and @ConditionalOnMissingBean

Jarvis Interviews
Jarvis