Home

markdown notes

Spring Core

table of contents


Dependency Injection

Process where objects use their dependent objects without a need to define or create them is called Dependency injection.

We can inject dependent objects in three ways, using:

Dependency Injection in Spring official doc

Null-Safety

@Service
public class EmailService {
    @Autowired
    private EmailValidator emailValidator;
}

Immutability

Design Problem - Single Responsibility

Design Problem Circular Dependencies

Testing Field Injection

@Component used as syncronized

Key Approaches to Synchronization in Spring Components

@Component
public class MyComponent {
    private int count = 0;
    private final Object lock = new Object();

    // Only one thread can enter this method per instance
    public synchronized void increment() {
        count++;
    }

    public void doTask() {
        // Specific critical section
        synchronized(lock) {
            // ... thread-safe code ...
        }
    }
}

Considerations and Best Practices

Note: In many scenarios, if the component is stateless, no synchronization is required at all.

ReentrantLock instead of synchronized

import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

@Component
public class SmartInventoryComponent {
    private final ReentrantLock lock = new ReentrantLock(); // Add 'true' for fairness
    private int stock = 100;

    public void updateStockWithTimeout() throws InterruptedException {
        // Try to get the lock within 2 seconds instead of waiting forever
        if (lock.tryLock(2, TimeUnit.SECONDS)) {
            try {
                stock--; 
            } finally {
                lock.unlock(); // Always unlock in finally
            }
        } else {
            // Handle failure to acquire lock (e.g., log a warning or return an error)
            System.out.println("Could not acquire lock, system busy");
        }
    }
}

While synchronized is simpler and often optimized by the JVM for low-contention scenarios, ReentrantLock offers specific advantages: