Deep Dive into Spring and Spring Boot: Advanced Concepts
After learning the basics of Spring and Spring Boot last week, it's time to dive deeper into some advanced yet essential topics. This guide will help you understand concepts like Dependency Injection, Autowiring, XML Configurations, and more, with clear explanations and examples to help you grasp them easily.
Topics Covered
Dependency Injection in Spring Boot
Autowiring in Spring Boot
Spring Without Boot
Spring XML Configuration
Constructor and Setter Injection in Spring Boot
Advanced Autowiring in Spring Boot
The Need for Spring Boot MVC
1. Dependency Injection in Spring Boot
What It Means:
Dependency Injection (DI) is a technique where the dependencies (other objects) of a class are provided from outside rather than being created inside the class. This makes the code cleaner, easier to test, and more reusable.
Code Example and Explanation:
@Service
public class UserService {
private final UserRepository userRepository;
// Dependency is injected via constructor
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public void performAction() {
userRepository.saveData();
}
}
Explanation:
UserService
depends onUserRepository
to perform some actions. Instead of creating aUserRepository
instance insideUserService
, we inject it using the constructor.Spring automatically creates and injects the required
UserRepository
instance because of the@Autowired
annotation.
2. Autowiring in Spring Boot
What It Means:
Autowiring is a feature of Spring that allows Spring to automatically inject the required beans into your class. This simplifies the process of wiring dependencies.
Code Example and Explanation:
@Component
public class OrderService {
@Autowired
private PaymentService paymentService;
public void processOrder() {
paymentService.makePayment();
}
}
Explanation:
The
@Autowired
annotation tells Spring to inject an instance ofPaymentService
intoOrderService
.No need to write
new PaymentService()
—Spring handles it for you.
3. Spring Without Boot
What It Means:
Spring Boot simplifies configuration, but sometimes you might need to set up a Spring application without it (e.g., for legacy projects). This involves creating beans and configuration manually.
Code Example and Explanation:
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService(userRepository());
}
@Bean
public UserRepository userRepository() {
return new UserRepository();
}
}
Explanation:
@Configuration
marks this class as a configuration file.@Bean
creates and registers beans (likeUserService
andUserRepository
) in the Spring application context.
This is less convenient but gives you full control over the configuration.
4. Spring XML Configuration
What It Means:
Before annotations became popular, Spring applications were configured using XML. Although less common now, it’s still used in some legacy systems.
Code Example and Explanation:
<beans>
<bean id="userService" class="com.example.UserService">
<property name="userRepository" ref="userRepository"/>
</bean>
<bean id="userRepository" class="com.example.UserRepository"/>
</beans>
Explanation:
The
<bean>
tag is used to define objects (UserService
andUserRepository
) in the XML file.The
ref
attribute connects theuserRepository
touserService
.
5. Constructor and Setter Injection in Spring Boot
What It Means:
These are two ways to inject dependencies into a class:
Constructor Injection: Dependencies are passed through the class’s constructor.
Setter Injection: Dependencies are set via setter methods.
Code Examples and Explanations:
Constructor Injection:
@Component
public class ProductService {
private final ProductRepository productRepository;
@Autowired
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
}
- The dependency (
ProductRepository
) is mandatory, so we inject it via the constructor.
Setter Injection:
@Component
public class CustomerService {
private CustomerRepository customerRepository;
@Autowired
public void setCustomerRepository(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
}
- Setter injection is better for optional dependencies or cases where the dependency might change.
6. Advanced Autowiring in Spring Boot
What It Means:
When multiple beans of the same type exist, you can use @Qualifier
to specify which one to inject.
Code Example and Explanation:
@Component
public class NotificationService {
private final MessageSender messageSender;
@Autowired
public NotificationService(@Qualifier("emailSender") MessageSender messageSender) {
this.messageSender = messageSender;
}
}
Explanation:
- The
@Qualifier("emailSender")
tells Spring to inject theemailSender
bean into theNotificationService
class, avoiding ambiguity.
7. The Need for Spring Boot MVC
What It Means:
Spring Boot MVC simplifies the creation of web applications by providing tools for building REST APIs, handling HTTP requests, and embedding servers.
Code Example and Explanation:
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users")
public List<User> getAllUsers() {
// Business logic to fetch users
return new ArrayList<>();
}
}
Explanation:
@RestController
is used to create REST APIs.@GetMapping
maps HTTP GET requests to thegetAllUsers
method.
Real-World Example: E-commerce Application
Scenario:
Imagine an e-commerce app with the following components:
ProductService
to manage products.OrderService
to handle customer orders.NotificationService
to send emails or SMS for order updates.
Code Implementation:
@Service
public class ProductService {
private final ProductRepository productRepository;
@Autowired
public ProductService(ProductRepository productRepository) {
this.productRepository = productRepository;
}
}
@Service
public class OrderService {
private final OrderRepository orderRepository;
private final NotificationService notificationService;
@Autowired
public OrderService(OrderRepository orderRepository, NotificationService notificationService) {
this.orderRepository = orderRepository;
this.notificationService = notificationService;
}
}
@Service
public class NotificationService {
@Autowired
private EmailSender emailSender;
public void sendNotification(String message) {
emailSender.sendEmail(message);
}
}
References
Wrapping Up
Spring and Spring Boot are powerful frameworks that simplify Java application development, whether for small-scale projects or enterprise-grade systems.
Key Takeaways for Beginners:
Dependency Injection and Autowiring are central to how Spring manages objects and dependencies.
Understanding XML and manual configuration helps you work with legacy projects.
Spring Boot simplifies the process further, making it easier to create production-ready web applications with embedded servers and REST APIs.
By combining these concepts, you can build scalable, maintainable, and efficient Java applications. Don’t forget to apply what you’ve learned by creating small projects, like a task manager or e-commerce system, to reinforce these skills.
Happy coding! 🚀