从 Spring Boot 2.2 开始,spring bean 可以是惰性的。也就是说,您可以在需要时创建 bean。让我们看看如何使用 Spring Boot 实现延迟初始化。
什么是延迟初始化?
默认情况下,Spring Framework 在上下文创建或刷新时创建并注入 bean 及其依赖项。但是使用惰性模式,我们可以在需要时初始化 bean。Spring 可以通过代理对象作为占位符 bean 来做到这一点。当这些代理发生调用时,Spring 可以检测并为它们创建适当的 bean。
如何启用延迟初始化?
延迟 bean 加载的概念对于 Spring 框架来说并不新鲜。但是 Spring Boot 2.2 只是让您更轻松。首先,有几种方法可以启用延迟初始化。他们是,
- 使用属性文件。
SpringApplication
使用或的内置方法SpringApplicationBuilder
。- 使用@Lazy注解
我们将逐一介绍这些方法。
使用应用程序属性
这种方法需要一个新引入的spring.main.lazy-initialization
属性条目。当设置为 时 true
,应用程序中的 bean 将被延迟加载。
spring.main.lazy-initialization=true
如果您使用的是 YAML,那么您应该使用以下配置。
spring:
main:
lazy-initialization: true
使用内置的 Spring Application 方法
您还可以lazyInitialization
在对象中设置标志SpringApplication
以启用延迟初始化。你可以通过两种方式做到这一点。
通过创建SpringApplication
对象并直接设置标志。
@SpringBootApplication
public class SpringBootLazyInitApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(SpringBootLazyInitApplication.class);
//设置延迟加载
application.setLazyInitialization(true);
application.run(args);
}
}
您还可以在使用SpringApplicationBuilder
.
@SpringBootApplication
public class SpringBootLazyInitApplication {
public static void main(String[] args) {
new SpringApplicationBuilder()
.main(SpringBootLazyInitApplication.class)
.lazyInitialization(true)
.build()
.run(args);
}
}
使用@Lazy注解
@Service
@Lazy
public class testService {
}
或者标记在配置类的自定义bean上
在 Spring Boot 中测试延迟初始化。
为了测试行为,我创建了一个故意花费 10 秒来创建的 bean。
@Service
public class HelloService {
public HelloService() {
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException ignored) {
}
}
public String hello() {
return "Hello There...!";
}
}
启动springboot 发现非常的慢
让我们启用延迟初始化并重新启动 Spring Boot 应用程序
正如您可以比较的那样,应用程序以这种方式启动得更快。这是因为应用程序不需要HelloService
。因此从未调用构造函数来创建 bean。
延迟初始化的优点
有多种情况下惰性初始化很有帮助。
- 延迟加载可以减少启动时间,因为加载的类更少,创建的 bean 也更少。
- 应用程序启动是一项 CPU 密集型任务。通过在需要时创建 bean,您可以随着时间的推移分散负载。
- 更快的启动时间在
Docker
和Kubernetes
平台中很有用。
延迟初始化的缺点
尽管延迟加载看起来很棒,但也存在一些潜在的风险。
- 与 Bean 创建相关的错误只能在加载 bean 时发现。如果没有延迟加载,我们可以在启动时识别它们。
- 诸如 no class def found 错误、OOM 错误以及由于配置错误导致的故障等故障在启动时会被忽视。
- 初始请求现在可能需要更多时间,因为应用程序必须创建 bean。
第三点非常关键,在我们web请求响应的时候第一次会非常的慢,因为我们并没有提前加载好bean,所以我们一般在指定的特定的bean上启用延迟加载
何时使用延迟初始化?
当应用程序较小时,延迟初始化很有帮助。它还具有使用概率较低的组件的位置。例如,具有异步通信的应用程序不需要担心初始性能下降。只要您的应用程序启动并接收消息,您就可以开始了。
开发人员可以在编写组件时设置此标志,因为他们只编写和测试一个或两个特定组件。理想情况下,这应该可以减少每次代码更改后重新加载应用程序的时间。