Inyección de Dependencias en Java: de la A a la Z en la práctica

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Inyección de Dependencias en Java: en la práctica



La Inyección de Dependencias (DI) es uno de los principios clave del desarrollo moderno en Java, que subyace en frameworks como Spring y Jakarta EE. En este artículo, analizaremos qué es la inyección de dependencias, por qué es necesaria y, lo más importante, cómo aplicarla en la práctica con ejemplos de código.



¿Qué es la Inyección de Dependencias y por qué es importante?



La Inyección de Dependencias es un patrón de diseño en el cual un objeto recibe sus dependencias desde el exterior, en lugar de crearlas por sí mismo. Esto implementa el principio de Inversión de Control (IoC). En lugar de que la clase gestione sus propias dependencias, el control se transfiere a un contenedor o fábrica externa.



Imagine que está escribiendo una aplicación para enviar notificaciones. Sin DI, su código podría verse así:



public class NotificationService {    private EmailSender emailSender = new EmailSender();

public void send(String message) { emailSender.send(message); }}


El problema es evidente: NotificationService está fuertemente acoplado a EmailSender. Si desea agregar notificaciones SMS o Push, tendrá que reescribir toda la clase. Con la Inyección de Dependencias, este problema se resuelve:



public class NotificationService {    private final MessageSender messageSender;

// La dependencia se pasa a través del constructor public NotificationService(MessageSender messageSender) { this.messageSender = messageSender; }

public void send(String message) { messageSender.send(message); }}


Ahora la clase depende de la abstracción MessageSender, no de una implementación concreta. Esto hace que el código sea flexible, comprobable y escalable.



Formas de inyectar dependencias en Java



Existen tres formas principales de implementar DI en Java. Veamos cada una con ejemplos.



1. Inyección por constructor (Constructor Injection)



Esta es la forma más preferible. Las dependencias se pasan a través de los parámetros del constructor y generalmente se marcan como final.



public class UserService {    private final UserRepository userRepository;    private final EmailService emailService;

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

public void registerUser(User user) { userRepository.save(user); emailService.sendWelcomeEmail(user.getEmail()); }}


Ventajas:

  • Las dependencias obligatorias son explícitamente visibles
  • El objeto siempre está en un estado válido
  • Ideal para objetos inmutables
  • Fácil de probar: basta con pasar objetos mock


2. Inyección por setters (Setter Injection)



Las dependencias se establecen a través de métodos setter después de crear el objeto.



public class OrderService {    private PaymentGateway paymentGateway;

public void setPaymentGateway(PaymentGateway paymentGateway) { this.paymentGateway = paymentGateway; }

public void processOrder(Order order) { paymentGateway.charge(order.getTotal()); }}


Cuándo usarlo: Para dependencias opcionales o cuando las dependencias pueden cambiar durante la vida del objeto. Sin embargo, este método hace que el objeto sea mutable y menos predecible.



3. Inyección por campo (Field Injection)



Se usa más a menudo con frameworks mediante anotaciones, por ejemplo @Autowired en Spring.



public class ReportService {    @Autowired    private DataSource dataSource;

public Report generateReport() { return dataSource

Blogs

Book Recommendations