Lazy-initialized Beans

默认情况下,Spring ApplicationContext 会预实例化所有单例 Bean。通常这很理想,因为它可以立即发现错误。但是,可以通过标记 Bean 为延迟初始化来阻止预实例化。延迟初始化的 Bean 仅在首次请求时创建实例,而不是在启动时。ただし、延迟初始化 Bean 如果依赖于非延迟初始化单例 Bean,则它们将在启动时创建。可以通过使用 @Lazy 注释或修改 XML 配置来控制单组 Bean 的延迟初始化行为。

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

By default, ApplicationContext implementations eagerly create and configure all singleton beans as part of the initialization process. Generally, this pre-instantiation is desirable, because errors in the configuration or surrounding environment are discovered immediately, as opposed to hours or even days later. When this behavior is not desirable, you can prevent pre-instantiation of a singleton bean by marking the bean definition as being lazy-initialized. A lazy-initialized bean tells the IoC container to create a bean instance when it is first requested, rather than at startup.

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

This behavior is controlled by the @Lazy annotation or in XML the lazy-init attribute on the <bean/> element, as the following example shows:

  • 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 会急切地预实例化。

When the preceding configuration is consumed by an ApplicationContext, the lazy bean is not eagerly pre-instantiated when the ApplicationContext starts, whereas the notLazy one is eagerly pre-instantiated.

但是,当延迟初始化 Bean 是一个不是延迟初始化的单例 Bean 的依赖时,ApplicationContext 会在启动时创建延迟初始化 Bean,因为它必须满足单例的依赖关系。延迟初始化 Bean 被注入到在别处的一个不是延迟初始化的单例 Bean 中。

However, when a lazy-initialized bean is a dependency of a singleton bean that is not lazy-initialized, the ApplicationContext creates the lazy-initialized bean at startup, because it must satisfy the singleton’s dependencies. The lazy-initialized bean is injected into a singleton bean elsewhere that is not lazy-initialized.

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

You can also control lazy-initialization for a set of beans by using the @Lazy annotation on your @Configuration annotated class or in XML using the default-lazy-init attribute on the <beans/> element, as the following example shows:

  • 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>