Guía Completa del Ciclo de Vida de un Bean en Spring
En Spring, el ciclo de vida de un bean se puede manejar tanto mediante configuración basada en anotaciones como mediante configuración XML. En esta guía, veremos cómo manejar ambos enfoques, primero a través de anotaciones y luego con XML, para gestionar el ciclo de vida de los beans. Ambas configuraciones siguen el mismo ciclo de vida, pero su implementación varía.
Fases del Ciclo de Vida de un Bean
- Creación del Bean
- Inyección de Dependencias
- Inicialización del Bean
- Destrucción del Bean
Configuración con Anotaciones
1. Creación del Bean
Con Spring, podemos definir beans mediante la anotación @Component
para clases que deben ser gestionadas por el contenedor de Spring.
Ejemplo usando anotaciones:
import org.springframework.stereotype.Component;
@Component
public class MyBean {
public MyBean() {
System.out.println("MyBean creado.");
}
}
El contenedor de Spring detectará el bean MyBean
gracias a la anotación @Component
, y se encargará de su creación cuando se inicie el contexto de la aplicación.
2. Inyección de Dependencias
La inyección de dependencias también se puede realizar con anotaciones como @Autowired
.
Ejemplo de inyección por constructor usando anotaciones:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MyService {
private final MyBean myBean;
@Autowired
public MyService(MyBean myBean) {
this.myBean = myBean;
System.out.println("MyService creado.");
}
}
3. Inicialización del Bean
Para inicializar un bean, podemos usar la anotación @PostConstruct
, que ejecuta un método después de que las dependencias hayan sido inyectadas.
Ejemplo de inicialización usando @PostConstruct
:
import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
@PostConstruct
public void init() {
System.out.println("Método de inicialización ejecutado.");
}
}
4. Destrucción del Bean
Para destruir un bean antes de que se cierre el contexto de Spring, podemos utilizar la anotación @PreDestroy
.
Ejemplo de destrucción usando @PreDestroy
:
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
@PreDestroy
public void cleanup() {
System.out.println("Método de destrucción ejecutado.");
}
}
Configuración del Contexto de Spring con Anotaciones
Para configurar el contenedor de Spring con anotaciones, usamos la anotación @Configuration
en una clase para indicar que esta clase es una configuración de Spring.
Ejemplo de configuración con anotaciones:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.ejemplo")
public class AppConfig {
// La anotación @ComponentScan detecta y registra los beans en el paquete especificado
}
Clase Principal con Spring Boot
El contenedor de Spring se inicia en una clase principal utilizando AnnotationConfigApplicationContext
o SpringApplication.run
en una aplicación Spring Boot.
Ejemplo de clase principal:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
Configuración con XML
Ahora, veamos cómo se realiza la misma configuración, pero usando XML.
1. Creación del Bean
En XML, los beans se definen dentro de un archivo de configuración como applicationContext.xml
mediante la etiqueta <bean>
.
Ejemplo de creación de un bean en XML:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myBean" class="com.ejemplo.MyBean"/>
</beans>
2. Inyección de Dependencias
La inyección de dependencias también puede configurarse en XML utilizando el atributo ref
.
Ejemplo de inyección por constructor en XML:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myBean" class="com.ejemplo.MyBean"/>
<bean id="myService" class="com.ejemplo.MyService">
<constructor-arg ref="myBean"/>
</bean>
</beans>
3. Inicialización del Bean
En XML, podemos definir métodos de inicialización utilizando el atributo init-method
.
Ejemplo de inicialización en XML:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myBean" class="com.ejemplo.MyBean" init-method="init"/>
</beans>
4. Destrucción del Bean
Al igual que la inicialización, la destrucción de beans también se configura en XML con el atributo destroy-method
.
Ejemplo de destrucción en XML:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myBean" class="com.ejemplo.MyBean" destroy-method="cleanup"/>
</beans>
Configuración del Contexto de Spring con XML
El contexto de Spring se configura a través de un archivo XML donde se definen todos los beans. Al igual que en la configuración basada en anotaciones, los beans se registran en el contenedor.
Ejemplo de archivo applicationContext.xml
:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myBean" class="com.ejemplo.MyBean"/>
<bean id="myService" class="com.ejemplo.MyService">
<constructor-arg ref="myBean"/>
</bean>
</beans>
Clase Principal con Spring
Para cargar el contexto en una aplicación basada en XML, se utiliza ClassPathXmlApplicationContext
.
Ejemplo de clase principal con XML:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApplication {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
MyService myService = context.getBean("myService", MyService.class);
}
}
Resumen
En Spring, el ciclo de vida de un bean es gestionado tanto por configuración basada en anotaciones como por configuración XML. En ambos casos, el ciclo de vida sigue las mismas etapas: creación, inyección de dependencias, inicialización y destrucción. Sin embargo, la forma de definir y configurar los beans varía según el enfoque elegido.
Ambas configuraciones permiten utilizar métodos personalizados de inicialización y destrucción, así como inyección de dependencias a través de constructores o setters.
Ejercicios para Practicar
Ejercicio 1: Crear un Bean con Inicialización y Destrucción en XML
- Crea un bean llamado
ProductService
y usa la configuración XML para definir el bean con un método de inicializacióninitialize
y un método de destruccióncleanup
.
Ejercicio 2: Inyección de Dependencias con XML y Anotaciones
- Crea dos clases:
ProductRepository
yProductService
. Usa la inyección de dependencias en ambas configuraciones (anotaciones y XML) para queProductService
dependa deProductRepository
.
Ejercicio 3: Configurar un Bean con Scope prototype
- Configura un bean con
scope="prototype"
en XML y anota otro bean con@Scope("prototype")
. Solicita el bean en ambas configuraciones y muestra cómo se crea una nueva instancia en cada caso.
Ejercicio 4: Configurar un Bean con @PostConstruct
y @PreDestroy
en una Clase con Configuración Anotada
- Crea un bean con anotaciones usando
@PostConstruct
para inicialización y@PreDestroy
para destrucción. Configura el bean en el contexto de Spring y prueba cómo se ejecutan los métodos de inicialización y destrucción.