
Dive Into Spring Core: Mastering DI, Annotations, and IoC
Madhuka Malshan / April 8, 2025
πΏ Introduction to Spring Core
If you're stepping into the world of Java enterprise development, Spring Core is your gateway. It's the foundation module of the Spring Framework, providing features for dependency injection, bean lifecycle management, and annotation-based configuration.
Letβs dive deep into Spring Core and understand why it's a game-changer for Java developers.
π‘ What is Spring Core?
Spring Core is a module that gives you the tools to manage the objects (beans) in your application through the concept of Inversion of Control (IoC) and Dependency Injection (DI).
π Inversion of Control (IoC)
Inversion of Control is a principle where the control of object creation and dependency resolution is handed over to the Spring Container, rather than being managed manually in your code.
Think of it like hiring a personal assistant: instead of you remembering to call the plumber, your assistant (Spring) does it for you automatically.
π§© Dependency Injection (DI)
Dependency Injection is a technique to supply objects (dependencies) a class needs without creating them inside the class. This makes your code:
- Easier to test
- Easier to maintain
- More flexible to extend
π§° Types of Dependency Injection
1. π§ͺ Constructor Injection (CI)
@Component public class Car { private final Engine engine; @Autowired public Car(Engine engine) { this.engine = engine; } }β
Best for mandatory dependencies
π« Slightly verbose if many dependencies
2. π§βπ§ Setter Injection (SI)
@Component public class Car { private Engine engine; @Autowired public void setEngine(Engine engine) { this.engine = engine; } }β
Best for optional dependencies
π« Can lead to partially initialized objects
π§ Real-World Analogy: DI Explained
Imagine you're building a computer:
- Without DI: You create all parts (CPU, RAM, HDD) inside the computer class.
- With DI: You receive all parts from an external supplier (Spring) and just assemble them.
ποΈ IoC Containers: BeanFactory vs ApplicationContext
Spring provides containers that manage the lifecycle of beans.
πΈ Lazy Initialization
BeanFactory: β Yes
ApplicationContext: β No (eager by default)
πΈ Internationalization Support
BeanFactory: β No
ApplicationContext: β Yes
πΈ Event Publishing
BeanFactory: β No
ApplicationContext: β Yes
πΈ AOP Integration
BeanFactory: β No
ApplicationContext: β Yes
𧬠Bean Scopes in Spring
πΉ singleton β One instance per Spring container (default)
πΉ prototype β A new instance is created every time itβs requested
πΉ request β One instance per HTTP request (for web applications)
πΉ session β One instance per HTTP session (for web applications)
@Component
@Scope("prototype")
public class Employee {}
π Annotations in Spring Core
Basic Annotations
@Componentβ Marks a class as a Spring-managed bean.@Autowiredβ Injects the dependency automatically.@Qualifierβ Helps resolve ambiguity with multiple beans.@Valueβ Injects primitive values or properties.
π¦ JSR-250 Annotations
JSR-250 provides Java-standard annotations that Spring supports:
@PostConstruct β This method is called after the bean has been initialized.
@PreDestroy β This method is called right before the bean is destroyed.
@Resource β Injects a dependency by name.
π¦ JSR-330 Annotations
These are from the javax.inject package:
@Inject β Serves as an alternative to Springβs @Autowired.
@Named β Can be used in place of @Component.
@Singleton β Ensures that only one instance of the bean is created.
𧬠Bean Lifecycle & Callbacks
The bean lifecycle includes:
- Instantiation
- Populating properties (DI)
@PostConstructorafterPropertiesSet()- Bean is ready for use
@PreDestroyordestroy()
βοΈ XML vs Annotation-based Config
Spring originally used XML for everything.
<bean id="myService" class="com.app.MyService"/>
Now we use annotations like:
@Component
public class MyService {}
β‘οΈ Annotation-based config is now the standard.
π§ Best Practices
β
Prefer Constructor Injection
β
Use @Qualifier for multiple implementations
β
Avoid field injection for testability
β
Use @PostConstruct instead of custom init methods
β
Use interfaces for better decoupling
π« Common Pitfalls
β Circular Dependencies (A needs B, B needs A)
β Mixing too many annotations without structure
β Overusing prototype scope in singletons
β Injecting optional beans without @Nullable or Optional
β Quick Quiz
- Which injection type is better for mandatory dependencies?
- What is the default scope of a Spring bean?
- Name one annotation from JSR-330.
- What's the difference between
@Componentand@Named?
π FAQ
Q: Is Spring Core only for web apps?
A: No! Spring Core can be used in any Java application.
Q: Can I mix XML and annotations?
A: Yes, though it's not recommended for large projects.
Q: Is @Inject the same as @Autowired?
A: Functionally, yes β but @Inject is from JSR-330.
π§ Whatβs Next?
- Spring Boot: Simplify Spring setup with auto-configuration
- Spring AOP: Handle cross-cutting concerns like logging and security
- Spring Data: Simplify database interactions