默认情况下,在Spring中创建应用程序上下文时会创建所有已定义的bean及其依赖项。
但是,当我们使用延迟初始化配置bean时,只会创建bean,并在需要时注入其依赖项。
Spring Boot 2中引入了spring.main.lazy-initialization属性,使得在整个应用程序中配置延迟初始化变得更加容易。
将属性值设置为true意味着应用程序中的所有bean都将使用延迟初始化。
在我们的application.properties文件中配置:
spring.main.lazy-initialization=true
此配置会影响上下文中的所有bean。而如果我们想为特定bean配置延迟初始化,我们可以通过@Lazy注解来实现。
更重要的是,我们可以将new属性与@Lazy注解结合使用,设置为false。
或者换句话说,除了那些我们用@Lazy(false)显式配置的bean之外,所有定义的bean都将使用延迟初始化。
让我们创建一个简单的服务,使我们能够测试刚刚描述的内容。
通过向构造函数添加打印消息,我们将确切知道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,而只在需要它们时才创建bean。
在整个应用程序中启用延迟初始化可能会产生正面和负面影响: