延迟初始化 Bean

默认情况下,ApplicationContext 实现在初始化过程的早期阶段就会创建并配置所有 singleton bean。通常,这种预实例化是可取的,因为配置或周围环境中的错误可以立即被发现,而不是在数小时甚至数天后。当不希望出现这种行为时,可以通过将 bean 定义标记为延迟初始化来阻止 singleton 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 是非延迟初始化的 singleton bean 的依赖项时,ApplicationContext 会在启动时创建该延迟初始化 bean,因为它必须满足 singleton 的依赖项。延迟初始化 bean 被注入到其他非延迟初始化的 singleton 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>