1.概述
Spring Boot 2.2开始在应用程序级别配置延迟初始化。
2.延迟初始化
在Spring中,默认情况下,所有定义的bean及其依赖项都是在创建应用程序上下文时创建的。
相反,当使用延迟初始化配置bean时,仅在需要bean时才创建该bean,并注入其依赖项。
3.Maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.4.3</version>
</dependency>
</dependencies>
4.启用延迟初始化
Spring Boot 2引入了spring.main.lazy-initialization属性,使在整个应用程序中配置延迟初始化变得更加容易。
将属性值设置为true意味着应用程序中的所有bean将使用延迟初始化。
在application.yml配置文件中配置属性:
spring:
main:
lazy-initialization: true
或者,在application.properties文件中:
spring.main.lazy-initialization=true
此配置影响上下文中的所有bean。 如果想为特定bean配置延迟初始化,可以通过@Lazy方法来完成。
更进一步,可以将new属性与@Lazy批注结合使用,设置为false。
换句话说,除了使用@Lazy(false)显式配置的那些bean外,所有定义的bean都将使用延迟初始化。
4.1.使用SpringApplicationBuilder
配置延迟初始化的另一种方法是使用SpringApplicationBuilder方法:
SpringApplicationBuilder(Application.class)
.lazyInitialization(true)
.build(args)
.run();
在上面的示例中,使用lazyInitialization方法来控制是否应延迟初始化应用程序。
4.2. 使用SpringApplication
另外,也可以使用SpringApplication类:
SpringApplication app = new SpringApplication(Application.class);
app.setLazyInitialization(true);
app.run(args);
在这里,使用setLazyInitialization方法将应用程序配置为延迟初始化。
要记住的一个重要注意事项是,在应用程序属性文件中定义的属性优先于使用SpringApplication或SpringApplicationBuilder设置的标志。
5. 运行
通过向构造函数添加一条消息,将确切地知道何时创建bean。
public class Writer {
private final String writerId;
public Writer(String writerId) {
this.writerId = writerId;
System.out.println(writerId + " initialized!!!");
}
public void write(String message) {
System.out.println(writerId + ": " + message);
}
}
另外,创建SpringApplication并注入之前创建的服务。
@SpringBootApplication
public class Application {
@Bean("writer1")
public Writer getWriter1() {
return new Writer("Writer 1");
}
@Bean("writer2")
public Writer getWriter2() {
return new Writer("Writer 2");
}
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
System.out.println("Application context initialized!!!");
Writer writer1 = ctx.getBean("writer1", Writer.class);
writer1.write("First message");
Writer writer2 = ctx.getBean("writer2", Writer.class);
writer2.write("Second message");
}
}
将spring.main.lazy-initialization属性值设置为false,然后运行应用程序。
Writer 1 initialized!!!
Writer 2 initialized!!!
Application context initialized!!!
Writer 1: First message
Writer 2: Second message
正如上面所说,bean是在应用程序上下文启动时创建的。
现在,将spring.main.lazy-initialization的值更改为true,然后再次运行应用程序。
Application context initialized!!!
Writer 1 initialized!!!
Writer 1: First message
Writer 2 initialized!!!
Writer 2: Second message
结果,该应用程序没有在启动时创建bean,而是仅在需要它们时才创建。
6.延迟初始化的影响
在整个应用程序中启用延迟初始化可能会产生积极和消极的影响。
-
延迟初始化可能会减少应用程序启动时创建的bean的数量–因此,我们可以缩短应用程序的启动时间
-
由于在需要它们之前都不会创建任何Bean,因此我们可以掩盖问题,使其在运行时而不是启动时运行。
-
这些问题可能包括内存不足错误,配置错误或发现类定义的错误
-
另外,当处于Web上下文中时,按需触发Bean创建会增加HTTP请求的延迟-Bean创建只会影响第一个请求,但这可能会对负载平衡和自动缩放产生负面影响。