Stage 10: Spring Core and Spring MVC, lesson 1 of 4

IoC and dependency injection

Intermediate3 min read@since 17Code runs on your Java 25
Explain it forThe essentials plus production detail and pitfalls.

Inversion of Control means objects don't create their own dependencies; a container creates them and wires them together. Dependency Injection is how Spring does it.

The ApplicationContext reads your configuration, creates beans (the objects it manages) and injects them wherever they're needed.

Injection styles:

  • Constructor injection (recommended): dependencies are explicit, can be final, and tests are easy. With a single constructor, @Autowired is optional.
  • Setter injection: for optional dependencies.
  • Field injection (@Autowired on a field): avoid it. It hides dependencies and needs reflection to test.

Register beans with stereotype annotations (@Component, @Service, @Repository, @Controller) found by component scanning, or with @Bean methods inside a @Configuration class.

Example

Java
public interface PaymentGateway { String charge(long paise); }

@Component
@Primary                                        // the default when several exist
class RazorpayGateway implements PaymentGateway {
    public String charge(long paise) { return "rzp_" + paise; }
}

@Component("stripe")
class StripeGateway implements PaymentGateway {
    public String charge(long paise) { return "str_" + paise; }
}

@Service
public class CheckoutService {
    private final PaymentGateway gateway;       // final and explicit

    public CheckoutService(PaymentGateway gateway) {   // constructor injection
        this.gateway = gateway;
    }
}

@Configuration
class AppConfig {
    @Bean
    Clock clock() { return Clock.systemUTC(); } // a third-party object as a bean
}

Common mistake

Two beans of the same type with no @Primary or @Qualifier. Startup fails with NoUniqueBeanDefinitionException.

Under the hood

Spring resolves a dependency by type first, then by @Qualifier or @Primary, then by parameter name. Constructor injection also exposes circular dependencies at startup; Spring Boot 2.6+ forbids circular references by default. Spring 6 and Boot 3 can compute the bean graph at build time (AOT processing), which GraalVM native images rely on.

Check yourself

Which injection style does the Spring team recommend for required dependencies?

How this connects

Part of Job-ready backend developer, Crack the Java interview.

Was this lesson helpful?

Finished reading? Mark it complete to track your progress.