Spring Framework 003 - Como inicializar los Beans
Para inicializar nuestro bean de Spring necesitamos indicar a Spring el <ode>init-method en el fichero XML o bien anotar un método público de nuestra clase java con @PostConstruct
.
Hemos visto cómo |instanciar e inyectar dependencias en un bean de Spring Framework. Veamos un ejemplo que tienes es la clase PostConstructSMain.java
El constructor del bean[editar]
Cuando Spring instancia una clase, por supuesto se ejecuta el constructor de la clase. Es un sitio donde podemos empezar a hacer cosas con nuestro código. Pero hacerlas ahí debería ser para cosas sencillas por dos motivos
- Se esta construyendo la clase, no deberíamos tardar mucho tiempo en hacer lo que tengamos que hacer y debe ser lo suficientemente seguro como para que no de errores. Si no, la clase tardará en instanciarse o fallar y eso afectará a nuestra aplicación al completo, que se arrancará más lento o fallará.
- Al ejecutarse el constructor, Spring todavía no ha inyectado las dependencias de otros beans. Por ello, no podemos usarlas.
Imagina la siguiente clase
public class PostConstructXMLSample {
Persona persona;
public PostConstructXMLSample(){
System.out.println("Instancian "+getClass() +" persona = "+persona);
}
// Getter y Setteer
}
Tiene un atributo Persona
que inyectaremos con Spring y un constructor donde se indica qué vale Persona
cuando se ejecuta el constructor. En un fichero XML de configuración de Spring, instanciamos la Persona
, la clase PostConstructXMLSample
y hacemos la ejecución
<bean id="Juan" class="com.chuidiang.pruebas.spring.Persona">
<property name="id" value="1"/>
<property name="nombre" value="Juan"/>
<property name="fechaNacimiento" value="11/23/1943"/>
</bean>
<bean class="com.chuidiang.pruebas.postconstruct.PostConstructXMLSample">
<property name="persona" ref="Juan"/>
</bean>
Si hacemos el main
de Spring que lee este fichero y lo arrancamos, veremos esto en pantalla
Instancian class com.chuidiang.pruebas.postconstruct.PostConstructAnnotatedSample persona = null
Es decir, se ejecuta el constructor pero a pesar de haber hecho la inyección de Persona
con Spring, todavía no está disponible.
Para hacer que se ejecute código después de haber recibido todas las dependencias, tenemos dos opciones, el fichero de configuración XML o bien las anotaciones.
init-method[editar]
Vamos con el caso de XML. A nuestra clase le añadimos un método con el nombre que queremos, por ejemplo init()
y el fichero XML de Spring solo tenemos que indicar que se llame a este método
public class PostConstructXMLSample {
Persona persona;
public PostConstructXMLSample(){
System.out.println("Instancian "+getClass() +" persona = "+persona);
}
public void init(){
System.out.println("Llaman init() "+getClass() +" persona = "+persona);
}
// Getter y Setter
}
y en el fichero XML
<bean id="Juan" class="com.chuidiang.pruebas.spring.Persona">
<property name="id" value="1"/>
<property name="nombre" value="Juan"/>
<property name="fechaNacimiento" value="11/23/1943"/>
</bean>
<bean class="com.chuidiang.pruebas.postconstruct.PostConstructXMLSample"
init-method="init">
<property name="persona" ref="Juan"/>
</bean>
Simplemente hemos añadido init-method
en el tag <bean>
. La ejecución de este código daría
Instancian class com.chuidiang.pruebas.postconstruct.PostConstructAnnotatedSample persona = null Llaman init() class com.chuidiang.pruebas.postconstruct.PostConstructAnnotatedSample persona = 1 Juan Tue Nov 23 00:00:00 CET 1943
Primero se llama al constructor, ya que se instancia la clase, pero Persona
no está disponible. Luego Spring llama a init()
cuando ya ha terminado de inyectar todas las dependencias.
@PostConstruct[editar]
La otra opción, si nos gusta más usar las anotaciones, es poner la anotación @PostConstruct
en el método init()
y en el fichero XML de Spring decir que haga caso a las anotaciones. La clase quedaría así
@Component
public class PostConstructAnnotatedSample {
@Autowired
Persona persona;
public PostConstructAnnotatedSample(){
System.out.println("Instancian "+getClass() +" persona = "+persona);
}
@PostConstruct
public void init(){
System.out.println("Llaman init() "+getClass() +" persona = "+persona);
}
// Getter y Setter
}
y el fichero XML de Spring
<context:component-scan base-package="com.chuidiang.pruebas.postconstruct"/>
<bean id="Juan" class="com.chuidiang.pruebas.spring.Persona">
<property name="id" value="1"/>
<property name="nombre" value="Juan"/>
<property name="fechaNacimiento" value="11/23/1943"/>
</bean>
Como vimos en [anotaciones con Spring], al poner context:component-scan
Spring mirará las anotaciones de las clases. Instanciará nuestra clase PostConstructAnnotatedSample
por tener la anotación @Component
, le inyectará la Persona
por tener la anotación @Autowired
y finalmente llamará al método init()
por tener la anotación @PostConstruct
.