英文:
Why does `SpringApplication.run` not create the beans lazily?
问题
如果您在项目中使用单例作用域定义了组件类,并且在 main()
中除了启动应用程序上下文之外什么都不做,例如:
ConfigurableApplicationContext context = SpringBootApplication.run(MyMainClass.class, args)
那么 context
已经指向包含这些类的单例实例的 ApplicationContext
。因此,无论您多少次键入 context.getBean(MyContainerClass.class)
,都将获得相同的 MyContainerClass
实例。
但是,创建该对象可能会非常耗费资源,甚至依赖于运行时约束(数据库连接、网络套接字管理等)。我理解过度使用构造函数不是很好的编程实践,但即使在普通的POJO中,它也可能发生。
我想知道是否存在一种特定的逻辑,可以在上下文创建时立即创建单例,而不是在第一次调用 getBean()
时创建。也许SpringBoot向程序员提供了这样的契约:“如果您已经用 @Component
注解了一个类,您确实应该在某个时候检索该bean:我会假设您知道这一点,并愿意在上下文启动时承担构造成本。”也许不是。不确定。
英文:
If you have defined component classes in your project with singleton scope and do nothing in your main()
besides bringing up the application context, e.g with:
ConfigurableApplicationContext context = SpringBootApplication.run(MyMainClass.class, args)
context
will already be pointing to an ApplicationContext
that contains a singleton instance of those classes. So no matter how many times you type context.getBean(MyContainerClass.class)
you will get the same instance of MyContainerClass
.
But the creation of that object might be quite heavy, and even dependent on runtime constraints (database connections, network socket management, the works). I understand that it is not very good programming practice to overload a constructor but, even in POJO, it can happen.
I was wondering whether there was a particular kind of logic to creating the singletons immediately when the context is created, instead of the first time getBean()
is called. Maybe there's a contract from SpringBoot to the programmer that says: "If you have annotated a class with @Component
, you really should retrieve the bean at some point: I will assume you know this and are willing to eat the construction cost when the context is being brought up." Maybe not. Not sure.
答案1
得分: 1
实际上,Spring Boot(2.3.3)可以对@Beans
进行惰性加载。只需将以下属性添加到您的application.properties
文件中。初始化应该是惰性执行的。
spring.main.lazy-initialization = true
在整个应用程序中启用惰性初始化可能会产生积极和消极的影响。有关惰性初始化效果的详细信息,请参见Baeldung的描述:
-
惰性初始化可以减少应用程序启动时创建的Bean数量 - 因此,我们可以改善应用程序的启动时间。
-
由于直到需要时才创建任何Bean,因此我们可以在运行时而不是启动时解决问题。
-
问题可能包括内存不足错误、配置错误或类定义未找到错误。
-
此外,当我们处于Web环境中时,按需触发Bean创建将增加HTTP请求的延迟 - Bean的创建仅影响第一个请求,但这可能对负载平衡和自动扩展产生负面影响。
英文:
actually the Spring Boot (2.3.3) can load the @Beans lazily. Just add the property below to your application.properties
file. The initialization should be performed lazily.
spring.main.lazy-initialization = true
Enabling lazy initialization in the whole application could produce both positive and negative effects. See the effects of Lazy Initialization described by Baeldung:
-
Lazy initialization may reduce the number of beans created when the application is starting – therefore, we can improve the startup time of the application
-
As none of the beans are created until they are needed, we could mask issues, getting them in run time instead of startup time
-
The issues can include out of memory errors, misconfigurations, or class-definition-found errors
-
Also, when we're in a web context, triggering bean creation on demand will increase the latency of HTTP requests – the bean creation will affect only the first request, but this may have a negative impact in load-balancing and auto-scaling.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论