Antes de sumergirnos en el ciclo de vida, repasemos brevemente qué es un bean en el contexto de Spring.
Un bean es un objeto que forma parte del contenedor de Spring y que es gestionado por este. Se crean, configuran y destruyen según las reglas definidas por el contexto de la aplicación. Los beans pueden ser cualquier clase de la aplicación que se anote con:
@Component
@Service
@Repository
@Controller
O bien ser definidos manualmente en clases de configuración con la anotación @Bean
.
El ciclo de vida de un bean en Spring Boot consta de varias etapas, desde su creación hasta su eliminación. Estas etapas son las siguientes:
1. Instanciación
2. Población de dependencias (Dependency Injection)
3. Inicialización
4. Uso del Bean
5. Destrucción
Vamos a analizar cada una de estas fases con más detalle.
La primera fase es la instanciación, donde el contenedor de Spring crea una instancia del bean utilizando su constructor predeterminado (o mediante inyección de dependencias en el constructor).
Ejemplo de una clase de servicio:
@Component
public class MiServicio {
public MiServicio() {
System.out.println("Bean MiServicio instanciado");
}
}
En esta etapa, el contenedor aún no ha inyectado dependencias ni ha llamado a métodos de inicialización.
Una vez que el bean ha sido instanciado, Spring procede a inyectar las dependencias definidas en la clase mediante inyección por constructor, setter o campos anotados con @Autowired
.
Ejemplo de inyección de dependencia:
@Component
public class ClienteServicio {
private final MiServicio miServicio;
@Autowired
public ClienteServicio(MiServicio miServicio) {
this.miServicio = miServicio;
System.out.println("Dependencia MiServicio inyectada en ClienteServicio");
}
}
En esta fase, el bean ya tiene todas sus dependencias necesarias configuradas.
Después de la inyección de dependencias, el contenedor de Spring ofrece mecanismos para ejecutar tareas de inicialización. Esto se puede hacer mediante:
InitializingBean
@PostConstruct
initMethod
)
@PostConstruct
@Component
public class MiServicio {
@PostConstruct
public void init() {
System.out.println("Método de inicialización ejecutado");
}
}
InitializingBean
@Component
public class MiServicio implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Inicialización mediante InitializingBean");
}
}
@Configuration
public class AppConfig {
@Bean(initMethod = "init")
public MiServicio miServicio() {
return new MiServicio();
}
}
Estos enfoques permiten realizar acciones como establecer valores predeterminados o abrir conexiones necesarias. 🔧
En esta fase, el bean ya está listo para ser utilizado en la aplicación a través de inyecciones en otras clases o recuperado desde el contexto de Spring mediante ApplicationContext
.
Ejemplo de uso:
@Autowired
private MiServicio miServicio;
El bean permanecerá activo mientras la aplicación lo necesite.
Cuando el contexto de la aplicación se cierra, Spring destruye los beans de forma ordenada para liberar recursos. Se pueden ejecutar acciones personalizadas durante la destrucción utilizando:
@PreDestroy
DisposableBean
destroyMethod
)
@PreDestroy
@PreDestroy
public void destroy() {
System.out.println("Liberando recursos del bean antes de la destrucción");
}
DisposableBean
@Component
public class MiServicio implements DisposableBean {
@Override
public void destroy() throws Exception {
System.out.println("Destrucción mediante DisposableBean");
}
}
@Configuration
public class AppConfig {
@Bean(destroyMethod = "destroy")
public MiServicio miServicio() {
return new MiServicio();
}
}
Es recomendable utilizar estos métodos para cerrar conexiones a bases de datos o limpiar recursos no gestionados por el framework. 🗑️
Para resumir, el ciclo de vida de un bean en Spring Boot sigue estos pasos:
1. Instanciación: Se crea el objeto del bean.
2. Inyección de dependencias: Se configuran todas las propiedades necesarias.
3. Inicialización: Se ejecutan acciones previas al uso del bean.
4. Uso: El bean es utilizado dentro de la aplicación.
5. Destrucción: Se liberan recursos y se eliminan instancias.
Cada una de estas fases ofrece puntos de intervención para personalizar el comportamiento del bean según nuestras necesidades.
Comprender el ciclo de vida de los beans en Spring Boot es esencial para aprovechar al máximo el framework y garantizar una gestión eficiente de los recursos. Ya sea mediante métodos de inicialización, destrucción o la inyección de dependencias, Spring nos proporciona múltiples mecanismos para controlar cada etapa.
Jorge García
Fullstack developer