延迟初始化 Bean

默认情况下,ApplicationContext 实现会在初始化过程中急切地创建和配置所有单例 Bean。通常,这种预实例化是可取的,因为配置或周围环境中的错误会立即被发现,而不是在数小时甚至数天后。当此行为不可取时,您可以通过将 Bean 定义标记为延迟初始化来阻止单例 Bean 的预实例化。延迟初始化的 Bean 会告诉 IoC 容器在首次请求时创建 Bean 实例,而不是在启动时。

此行为由@Lazy注解控制,或者在 XML 中由<bean/>元素上的lazy-init属性控制,如下例所示

  • Java

  • Kotlin

  • Xml

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

@Bean
AnotherBean notLazy() {
	return new AnotherBean();
}
@Bean
@Lazy
fun lazy(): ExpensiveToCreateBean {
	return ExpensiveToCreateBean()
}

@Bean
fun notLazy(): AnotherBean {
	return AnotherBean()
}
<bean id="lazy" class="com.something.ExpensiveToCreateBean" lazy-init="true"/>

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

当上述配置被ApplicationContext使用时,lazy Bean 在ApplicationContext启动时不会被急切地预实例化,而notLazy Bean 会被急切地预实例化。

但是,当延迟初始化的 Bean 是未延迟初始化的单例 Bean 的依赖项时,ApplicationContext会在启动时创建延迟初始化的 Bean,因为它必须满足单例的依赖项。延迟初始化的 Bean 被注入到其他地方的单例 Bean 中,该单例 Bean 未延迟初始化。

您还可以通过在@Configuration注解的类上使用@Lazy注解,或在 XML 中使用<beans/>元素上的default-lazy-init属性来控制一组 Bean 的延迟初始化,如下例所示

  • Java

  • Kotlin

  • Xml

@Configuration
@Lazy
public class LazyConfiguration {
	// No bean will be pre-instantiated...
}
@Configuration
@Lazy
class LazyConfiguration {
	// No bean will be pre-instantiated...
}
<beans default-lazy-init="true">

	<!-- No bean will be pre-instantiated... -->
</beans>