ApplicationContext, FactoryBeans, PropertyEditors, y ciclo de vida de beans

Continuamos profundizando en los aspectos básicos de Spring. Como el movimiento se demuestra andando… ¡vamos a empezar!

Entendiendo los PropertyEditors

Estos elementos permiten convertir objetos a partir de String y viceversa. Vamos a ver un ejemplo. Supongamos que queremos que queremos inyectar fechas en formato “dd/MM/yyyy”, en Spring 4 podríamos registrar un PropertyEditor. En primer lugar indicaríamos como hacer la conversión utilizando una clase que implemente “PropertyEditorRegistrar”:

Seguidamente registraríamos esta clase en la lista de editores:

Como se puede ver con CustomEditorConfigurer registramos nuestro editor de propiedades. Tenemos una clase “EjemploDate” a la que inyectamos la fecha. La clase tiene esta pinta:

De este modo conseguimos inyectar fechas automáticamente desde cadenas de texto. Hemos necesitado registrar la conversión de Date, ya que Spring no registra este editor por defecto. Existen otros PropertyEditors que podemos utilizar directamente y que no hace falta registrar. Por ejemplo, podemos asignar directamente valores a estos tipos:

Que inyectaríamos de este modo:

 También podemos crear nuestro propio PropertyEditor y registrarlo, para ello tenemos que crear una clase que extienda de PropertyEditorSupport.

BeanNameAware y ApplicationContextAware

BeanNameAware es un interfaz que nos permite obtener el nombre del bean y ApplicationContextAware es otro interfaz que nos permite acceder al contexto de aplicación. Estos dos interfaces son extremadamente útiles, veamos un ejemplo:

Spring automáticamente se encarga de hacer llegar el nombre (el id) y el contexto a nuestro bean. Es muy útil disponer del id del bean, nos puede servir para escribir trazas, o para emplearlo en los elementos de nuestra aplicación.

Acceder a ficheros y recursos

Utilizando las utilidades que nos proporciona la clase ApplicationContext es muy sencillo acceder a recursos en nuestra aplicación. De este modo:

El interfaz Resource proporciona múltiples métodos para manipular los recursos.

Uso de FactoryBeans

Este mecanismo nos permite crear beans a partir de clases de terceros que no se pueden usar como beans (que bien me explico…).
Creo que esto se ve mejor con un ejemplo. Imaginemos que queremos un bean de tipo Callendar que sirva como fecha de referencia, de modo que podamos inyectarlo a otras clases. Este bean, no se puede utilizar directamente, ya que para obtener una instancia de esta clase, tenemos que llamar a Calendar.getInstance(). Podemos crear una factoría de este modo:

Los métodos que hay que implemetar permiten que Spring obtenga toda la información necesaria para obtener una instancia del bean. Podríamos modificar la clase anterior para inyectar las propiedades que quisieramos de modo que el Calendar creado podría estár inicializado a la zona horaria o a la fecha que más nos convenga. Ahora podemos crear el bean e inyectarlo en las clases que nos interese. Por ejemplo, imaginemos que tenemos estas dos clases:

Ya podemos inyectar el calendario en las dos clases, de este modo:

Vamos a probar lo que hemos hecho:

Si leemos la consola, comprobaremos que se escriben los mismos milisegundos.
Otro modo de crear crear un bean de tipo Calendar puede ser el siguiente:

Existen otras maneras de utilizar FactoryBean, por ejemplo, podemos crear una clase simple, que no implemente ningún interfaz, como la siguiente:

Y utilizarla a través de “factory-bean” y “factory-method” del siguiente modo:

Ejecución de un método al crear un bean

En ocasiones necesitamos realizar operaciones de inicialización de los beans después de que se haya ejecutado el código del constructor y tras la ejecución de los getters/setters de nuestras clases. Hay que comentar que los mecanismos que vamos a comentar no es aplicable a los beans con alcance “prototype”.

Esto se puede realizar invocando al método de inicialización desde el fichero xml, de este modo:

Como se puede ver, se indica el nombre del método de inicialización “init()” que se va a invocar. El segundo modo de realizar esto es implementando el método “afterPropertiesSet()” del interfaz “InitializingBean“. Por ejemplo:

El tercer modo de realizar esto es con la anotación @PostConstruct de JSR-250 por ejemplo:

 

Ejecutar un método cuando se destruye el bean

Del mismo modo que podemos ejecutar código cuando se crean los beans, se puede ejecutar código cuando se destruye. La invocación al método de destrucción se realiza invocando al método “destroy()” del contexto, por ejemplo:

Como se puede ver, la invocación al método “destroy()” no se dispara automáticamente. Si estamos en una aplicación web, podemos invocar a este método cuando se ejecute el método “destroy()” del servlet, pero en aplicaciones standalone, la cosa se complica, sobre todo si tenemos varios puntos de salida en la aplicación. Para que se dispare este mecanismo podemos usar un “Shutdown Hook” que es un hilo que ejecuta java cuando la aplicación se cierra. Lo podemos hacer de este modo:

Lo podemos realizar en el fichero xml de configuración, mediante la etiqueta “destroy-method

El segundo modo de hacer esto es a través del método “destroy()” del interfaz “DisposableBean“:

Y como en el caso anterior, el tercer modo de hacer esto es con la anotación JSR-250 @PreDestroy:

Bien, lo vamos a dejar aquí. Como se puede ver todas estas herramientas son de gran utilidad en el desarrollo de nuestras aplicaciones. Si te ha gustado el artículo no dudéis en poner un comentario. Recordad que los comentarios son moderados y no se muestran inmediatamente. Podéis consultar otros artículos sobre Spring aquí

 

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *