懒初始化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使用时,在ApplicationContext启动时,lazy类型的bean不会被立即预实例化(即不会在启动时就创建其对象),而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>