Lazy Initialized Beans

Beans con inicialización diferida

De forma predeterminada, las implementaciones de ApplicationContext crean y configuran anticipadamente todos los beans singleton durante el proceso de inicialización. Por lo general, esta preinstanciación es conveniente, ya que permite detectar de inmediato errores en la configuración o en el entorno, en vez de descubrirlos horas o incluso días después.

Cuando este comportamiento no sea deseable, puedes impedir la preinstanciación de un bean singleton marcando su definición para que se inicialice de forma diferida (lazy initialization).

Un bean con inicialización diferida indica al contenedor IoC que debe crear la instancia del bean la primera vez que se solicite, en lugar de crearla durante el arranque de la aplicación.

Este comportamiento se controla mediante la anotación @Lazy o, en XML, con el atributo lazy-init en el elemento <bean/>, como muestran los siguientes ejemplos.

Configuración con Java

@Bean
@Lazy
ExpensiveToCreateBean lazy() {
    return new ExpensiveToCreateBean();
}

@Bean
AnotherBean notLazy() {
    return new AnotherBean();
}

Configuración con Kotlin

@Bean
@Lazy
fun lazy(): ExpensiveToCreateBean {
    return ExpensiveToCreateBean()
}

@Bean
fun notLazy(): AnotherBean {
    return AnotherBean()
}

Configuración con XML

<bean id="lazy" class="com.something.ExpensiveToCreateBean" lazy-init="true"/>

<bean name="notLazy" class="com.something.AnotherBean"/>

Cuando un ApplicationContext consume la configuración anterior, el bean lazy no se preinstancia al iniciarse el contexto. En cambio, el bean notLazy sí se preinstancia de manera anticipada.

Sin embargo, cuando un bean de inicialización diferida es una dependencia de un bean singleton que no tiene inicialización diferida, ApplicationContext crea el bean diferido durante el arranque. Esto ocurre porque debe satisfacer las dependencias del singleton no diferido. En otras palabras, aunque el bean esté marcado como @Lazy, se creará al inicio si otro singleton no diferido lo necesita.

También puedes controlar la inicialización diferida para un conjunto de beans. Para ello, usa la anotación @Lazy en una clase anotada con @Configuration o, en XML, el atributo default-lazy-init en el elemento <beans/>.

Configuración global con Java

@Configuration
@Lazy
public class LazyConfiguration {
    // Ningún bean se preinstanciará...
}

Configuración global con Kotlin

@Configuration
@Lazy
class LazyConfiguration {
    // Ningún bean se preinstanciará...
}

Configuración global con XML

<beans default-lazy-init="true">

    <!-- Ningún bean se preinstanciará... -->

</beans>