Ciclo de vida de un Spring Bean

By | 19 abril 2014

A la hora de desarrollar una aplicación con Spring Framework, es fundamental tener en cuenta el ciclo de vida de los beans que vamos a declarar en nuestra aplicación, por dos razones fundamentales.

  • Dependencias de otros beans, puesto que algunos beans van a requerir que otros ya estén creados previamente.
  • Activación retardada de ciertos servicios, por ejemplo, que existan tareas previas en la inicialización de nuestra aplicación que configuren ciertos servicios necesarios para que otros funcionen correctamente.

Spring nos ofrece diferentes mecanismos para controlar este ciclo de vida, desde la posición en la creación de la cadena de beans, hasta la ejecución de determinados métodos, toda la información de la que voy a hablar en este post, y muchas mas la podéis encontrar en este capitulo de Spring Reference, yo simplemente me voy a dedicar a nombraros los aspectos mas destacables de esa sección.

Así por ejemplo, las anotaciones @PostConstruct y @PreDestroy se tratan de dos anotaciones usadas de forma muy común en el desarrollo de aplicaciones con Spring.

@PostConstruct nos permite ejecutar un método de nuestro bean una vez que este ha resuelto todas sus inyecciones de dependencia.

@PreDestroy nos permite ejecutar un método de nuestro bean cuando este va a ser destruido del contexto de Spring.

@Service
public class AppService {

    @Autowired
    private Worker worker;

    private int numWorkers = 0;

    public AppService(){

    }

    @PostConstruct
    public void init(){

        this.numWorkers = this.worker.getWorkers().size();
    }

    @PreDestroy
    public void reset(){

        this.numWorkers = 0;
    }

}

Estas dos anotaciones no son la única manera de implementar esta funcionalidad en nuestros beans, también existen dos interfaces InitializingBean y DisposableBean, así como dos parámetros configurables desde xml, init-method y destroy-method que nos permiten realizar las mismas funcionalidades.

Eso si, si decidimos combinarlos, tendremos que tener en cuenta su orden de ejecución.

En inicialización:

  1. Primero los métodos anotados con @PostConstruct.
  2. Los métodos sobre escritos de InitializingBean.
  3. Los métodos especificados por init-method.

En destrucción:

  1. Primero los métodos anotados con @PreDestroy.
  2. Los métodos sobre escritos de DisposableBean .
  3. Los métodos especificados por destroy-method.

Por ultimo, para definir la posición en la cadena de creacion de Beans, Spring nos provee de la interface Phased, la cual nos obliga a implementar un metodo, getPhased() que retorna la posición en forma de entero, por defecto todos los beans tienen un valor de 0.

De esta manera, si asignamos un valor inferior a 0, nuestro bean sera el primero en ser creado y el ultimo en ser destruido, y si le asignamos un valor superior a 0, será el ultimo en ser creado y el primero en ser destruido.

@Service
public class AppService implements Phased{

    @Autowired
    private Worker worker;

    private int numWorkers = 0;

    public AppService(){

    }

    @PostConstruct
    public void init(){

        this.numWorkers = this.worker.getWorkers().size();
    }

    @PreDestroy
    public void reset(){

        this.numWorkers = 0;
    }

    @Override
    public int getPhase() {

        return 10;
    }

}
Comparte esta entrada enShare on LinkedIn0Tweet about this on Twitter0Share on Facebook0Share on Google+0

Deja un comentario

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