我有一个spring应用程序,并且有一个计划逻辑,它以固定速率生成原型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!)
...
这是第一个预定的电话。看起来像是一个时间问题。在我的笔记本电脑上,应用程序初始化的速度要快得多,并且第一次调度调用(生成原型bean)没有任何错误。
有没有办法了解Spring bean创建流程的当前状态,以便我可以在计划逻辑中检查它,并且在应用程序创建未完成时不产生任何内容?
谢谢!
答案 0 :(得分:1)
查看Spring源代码(4.3.3和4.2.2),这只发生在一个位置DefaultSingletonBeanRegistry.getSingleton()中,并且仅在spring上下文的初始化失败时,或者您已明确关闭它。 Spring使用单个线程(调用线程)来创建bean并调用start生命周期方法,因此只有在违反此原则时才能发现异常。
我见过很多开发人员在bean构造函数中启动线程,这是一个非常糟糕的主意。如果你有一个带有生命周期的bean(线程,资源池),你应该总是使用LifeCycle接口,并在start()中创建你的资源,并在stop()中清理它。这是一个好主意,因为在实例化每个eager单例并完全连接上下文之后调用start(),因此除非可以构造每个bean,否则不会创建任何线程。