Home/Learn/Spring Boot/Dependency Injection

Dependency Injection

Beginner
Core & Setup

Spring's DI container wires your application together. Understanding @Component stereotypes, @Bean factory methods, @Qualifier disambiguation, and scope is essential for every Spring developer.

Overview

Spring's component model uses stereotype annotations to classify beans: @Component (generic), @Service (business logic), @Repository (data access — also adds persistence exception translation), @Controller/@RestController (web layer). @Configuration + @Bean defines beans explicitly when you need constructor arguments or third-party classes. When multiple beans satisfy an injection point, @Qualifier or @Primary resolves the ambiguity. Bean scope (singleton, prototype, request, session) controls how many instances are created.

@Component Stereotypes

The four stereotypes are semantically equivalent to @Component but communicate intent and enable framework features. @Repository adds PersistenceExceptionTranslationPostProcessor support, translating database-specific exceptions into Spring's DataAccessException hierarchy.

Java — @Service, @Repository, @Component
// @Service — business logic, no extra framework magic
@Service
public class UserService {
    private final UserRepository userRepository;
    private final EmailService emailService;

    public UserService(UserRepository userRepository, EmailService emailService) {
        this.userRepository = userRepository;
        this.emailService = emailService;
    }

    public User register(RegisterRequest req) {
        if (userRepository.existsByEmail(req.email())) {
            throw new EmailAlreadyExistsException(req.email());
        }
        User user = new User(req.email(), passwordEncoder.encode(req.password()));
        User saved = userRepository.save(user);
        emailService.sendWelcome(saved); // fire and forget
        return saved;
    }
}

// @Repository — data access layer
// Also translates SQLExceptions to DataAccessException
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);
    boolean existsByEmail(String email);
}

// Plain @Component — doesn't fit other stereotypes
@Component
public class SlugGenerator {
    public String generate(String title) {
        return title.toLowerCase().replaceAll("\s+", "-");
    }
}

@Configuration and @Bean

Use @Bean methods inside @Configuration classes to register third-party classes or beans that need complex initialization. @Configuration classes are proxied by CGLIB so @Bean method calls between them return the same singleton instance.

Java — @Configuration with @Bean methods
@Configuration
public class AppConfig {

    // Register third-party class as a Spring bean
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(12); // cost factor 12
    }

    // Bean with dependencies (injected as method parameters)
    @Bean
    public ObjectMapper objectMapper() {
        return Jackson2ObjectMapperBuilder.json()
            .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .modules(new JavaTimeModule())
            .build();
    }

    // Conditional bean — only if property is set
    @Bean
    @ConditionalOnProperty(name = "feature.email.enabled", havingValue = "true")
    public EmailClient emailClient(
            @Value("${email.api.key}") String apiKey) {
        return new ResendEmailClient(apiKey);
    }
}

@Qualifier, @Primary and Bean Scopes

When two beans implement the same interface, @Primary marks the default and @Qualifier picks a specific one by name. Bean scope controls how many instances exist: singleton (default, one per context), prototype (new instance per injection), request (one per HTTP request — needs web context).

Java — @Primary, @Qualifier, bean scopes
// Two implementations of the same interface
@Service("razorpayPayment")
public class RazorpayPaymentService implements PaymentService { ... }

@Service("paypalPayment")
@Primary  // used when no @Qualifier specified
public class PaypalPaymentService implements PaymentService { ... }

// Injecting a specific one
@Service
public class CheckoutService {
    private final PaymentService razorpay;
    private final PaymentService paypal;

    public CheckoutService(
            @Qualifier("razorpayPayment") PaymentService razorpay,
            @Qualifier("paypalPayment")  PaymentService paypal) {
        this.razorpay = razorpay;
        this.paypal   = paypal;
    }
}

// Prototype scope — new instance every time
@Component
@Scope("prototype")
public class ReportGenerator {
    // Stateful — each caller gets its own instance
}

// Request scope — one per HTTP request
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST,
       proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestContext {
    private String correlationId;
}

Key Points to Remember

  • 1@Service, @Repository, @Controller are specializations of @Component — use them to communicate layer intent.
  • 2@Repository adds persistence exception translation: vendor SQLExceptions → Spring DataAccessException.
  • 3Use @Bean methods in @Configuration classes for third-party objects or beans needing complex setup.
  • 4@Primary sets a default when multiple beans satisfy a type; @Qualifier picks a specific named bean.
  • 5Singleton scope (default) means one shared instance — never store mutable request state in a singleton.
  • 6Prototype scope creates a new instance per injection; request scope creates one per HTTP request.

Interview Questions

Sign in to ask Aria
1

What is the difference between @Component, @Service, and @Repository?

EasyTCS
2

When would you use @Bean instead of @Component?

EasyWipro
3

What happens when two beans of the same type exist and you use @Autowired without @Qualifier?

MediumInfosys
4

How do you inject a prototype-scoped bean into a singleton?

HardGoldman Sachs
5

What is @Primary and how does it differ from @Qualifier?

MediumRazorpay

Ask Aria about Dependency Injection

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…