Spring
01 / 05

Spring Core: IoC & Dependency Injection

Spring: IoC & Dependency Injection

Spring's IoC (Inversion of Control) container manages object creation and lifecycle. Beans are objects managed by Spring. Dependency Injection wires dependencies automatically — you declare what you need, Spring provides it.

Bean Annotations

// @Component and its specializations
@Component          // generic Spring-managed bean
@Service            // business logic layer (semantic alias of @Component)
@Repository         // data access layer — also translates SQL exceptions
@Controller         // MVC web controller
@RestController     // @Controller + @ResponseBody on all methods

// Configuration class — defines beans explicitly
@Configuration
public class AppConfig {

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

    @Bean
    @Primary                             // preferred when multiple implementations exist
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create()
            .url("jdbc:postgresql://localhost/mydb")
            .build();
    }
}

Dependency Injection

// Constructor injection — RECOMMENDED
@Service
public class UserService {
    private final UserRepository userRepository;
    private final EmailService emailService;

    // Spring automatically injects — @Autowired optional since Spring 4.3
    public UserService(UserRepository userRepository, EmailService emailService) {
        this.userRepository = userRepository;
        this.emailService = emailService;
    }
}

// Field injection — discouraged (hard to test, hides dependencies)
@Autowired
private UserRepository userRepository;  // avoid this

// Qualifier — when multiple beans implement the same interface
@Service
public class NotificationService {
    public NotificationService(
        @Qualifier("emailNotifier") Notifier emailNotifier,
        @Qualifier("smsNotifier")   Notifier smsNotifier) { }
}

// Optional injection
@Autowired(required = false)
private MetricsService metricsService;   // null if not in context

Bean Scopes & Lifecycle

// Scopes
@Scope("singleton")   // default — one instance per container
@Scope("prototype")   // new instance every time injected
@Scope("request")     // one per HTTP request (web apps)
@Scope("session")     // one per HTTP session (web apps)

// Lifecycle callbacks
@Component
public class CacheManager {

    @PostConstruct          // called after DI is complete
    public void init() {
        loadCache();
    }

    @PreDestroy             // called before bean is removed from context
    public void cleanup() {
        flushCache();
    }
}

// Conditional beans
@Bean
@ConditionalOnProperty(name = "feature.email", havingValue = "true")
public EmailService emailService() { return new SmtpEmailService(); }

@Bean
@Profile("development")
public DataSource h2DataSource() { return new EmbeddedDatabaseBuilder().build(); }

@Bean
@Profile("production")
public DataSource postgresDataSource() { /* ... */ }

ApplicationContext & Events

// Access context directly (use sparingly — prefer constructor injection)
@Component
public class BeanFactory implements ApplicationContextAware {
    private ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        this.context = ctx;
    }

    public <T> T getBean(Class<T> type) { return context.getBean(type); }
}

// Application events — decoupled communication
// Publish
@Service
public class UserService {
    private final ApplicationEventPublisher eventPublisher;

    public void createUser(User user) {
        userRepository.save(user);
        eventPublisher.publishEvent(new UserCreatedEvent(this, user));
    }
}

// Listen
@Component
public class WelcomeEmailListener {

    @EventListener
    @Async                     // handle in separate thread
    public void onUserCreated(UserCreatedEvent event) {
        emailService.sendWelcome(event.getUser());
    }
}

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free