java - Spring bean创建流程: how to know when it is finished?

标签 java spring spring-bean spring-ioc

我有一个 Spring 应用程序,并且有一个预定的逻辑,它以固定的速率生成原型(prototype) bean。

在我的笔记本电脑上一切正常,但将其部署到服务器后,我的应用程序无法启动,原因是:

2016-12-13 04:13:01.885 ERROR 4688 --- [TaskScheduler-1] o.s.s.s.TaskUtils$LoggingErrorHandler    : Unexpected error occurred in scheduled task.
...
BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationNotAllowedException: Error creating bean with name 'metaDataSourceAdvisor': Singleton bean creation not allowed
 while the singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)
...

这是第一次预定的通话。看来是时间问题。在我的笔记本电脑上,应用程序的初始化速度要快得多,并且第一次计划调用(生成原型(prototype) bean)不会发生任何错误。

有没有办法了解 Spring bean 创建流程的当前状态,以便我可以在计划逻辑中检查它,并且在应用程序创建未完成时不产生任何结果?

谢谢!

最佳答案

查看 Spring 源代码(4.3.3 和 4.2.2),这只发生在一个位置 DefaultSingletonBeanRegistry.getSingleton(),并且仅当 spring 上下文的初始化失败或您已显式关闭它时。 Spring 使用单个线程(调用线程)来创建 bean 并调用启动生命周期方法,因此只有在违反此原则时才可能出现您发现的异常。

  • 当你说计划任务时,你的意思是由Spring计划(使用@Scheduled),还是你有自己的计划逻辑?
  • 您是否在应用程序中启动了任何线程?如果是,拥有该线程的 Bean 是否实现了 Spring 的 Lifecycle 或 SmartLifecycle 接口(interface)?

我见过很多开发人员在 bean 构造函数中启动线程,这是一个非常糟糕的主意。如果您有一个具有生命周期的 bean(线程、资源池),您应该始终使用 LifeCycle 接口(interface),并在 start() 中创建资源,并在 stop() 中清理它。这是一个好主意,因为在实例化每个急切的单例并且上下文完全连接之后调用 start(),因此除非可以构造每个 bean,否则不会创建任何线程。

关于java - Spring bean创建流程: how to know when it is finished?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41118117/

相关文章:

java - JAX-WS,为什么收到的LinkedHashMap集合是空的?

java - 使用 Spring 数据批量插入

java - Spring Boot - 测试用例 - 不要加载所有组件

java - 如何仅使用注解将相同类型的bean组合到一个数组中?

java - 理解 Spring 4 注释 bean

java - 什么时候视频文件太大而无法在没有流式传输/分段的情况下发送?

java - 我可以更改 session 存储的根目录吗?

spring - 使用spring-cloud-starter-zuul时如何实现和配置route类型的ZuulFilter?

java - 具有外部属性的 Spring Boot 配置文件

java - AfterPropertiesSet 是加载 staticList 的正确位置吗?