如何延迟spring bean启动?
Posted
技术标签:
【中文标题】如何延迟spring bean启动?【英文标题】:How to delay spring beans startup? 【发布时间】:2011-03-28 11:36:02 【问题描述】:拥有运行 apache-activemq 服务器作为 spring bean 和几个 apache-camel 路由的 spring 应用程序(实际上是 grails 应用程序)。应用程序使用休眠来处理数据库。问题很简单。 Activemq+Camel 启动BEFORE
grails 将特殊方法注入休眠域对象(实际上是保存/更新方法等)。因此,如果 activemq 在启动时已经有一些数据 - Camel 开始处理消息而没有注入 Grails DAO 方法。 grails.lang.MissingMethodException
失败。在 Grails 将特殊方法注入域对象之前,必须延迟 activemq/camel 启动。
【问题讨论】:
【参考方案1】:如果所有这些都定义为spring bean,则可以使用
<bean id="activeMqBean" depends-on="anotherBean" />
这将确保anotherBean
在activeMqBean
之前初始化
【讨论】:
谢谢 Bonzo,但我知道depends-on
声明。不幸的是,它不起作用,因为 Grails 初始化与 Spring 在不同的层上。所以没有什么是 activemq 应该依赖的 bean。【参考方案2】:
您可以将 MQ 管理移动到插件中吗?它会增加模块化,如果你在插件描述符中声明
def loadAfter = ['hibernate']
你应该有想要的行为。适用于JBPM plugin
【讨论】:
好吧,老实说,我不会创建/维护单独的插件只是为了在加载休眠后启动 AMQ。我确信有更好的方法。 在 grails 中,插件是组件。我为应用程序开发了几个插件只是因为我认为它们会更好地模块化。插件也是集成遗留数据或系统的有用方法。在维护应用程序时维护它们。您不必将它们释放到野外。 我知道了 ;) 但无论如何 - 我不会将单个 activemq.xml 初始化文件从主应用程序移动到另一个具有完整 grails 插件项目结构的component
中,将其发布到 svn 和维护另一堆源只是为了延迟 AMQ 初始化。有更简单的方法。 AMQ bean 支持 start
属性,指示它是否应该自动启动。暂时使用它。【参考方案3】:
我不确定你的情况,但延迟加载也可能会有所帮助,例如
<bean id="lazybean" class="com.xxx.YourBean" lazy-init="true">
一个延迟初始化的 bean 指示 IoC 容器在第一次请求它时创建 bean 实例。这可以帮助您延迟加载所需的 bean。
【讨论】:
这也行不通,因为我的 DAO bean 肯定是在加载休眠之前请求的。【参考方案4】:我知道这个问题已经很老了,但我现在在 2015 年面临同样的问题 - 这个帖子没有为我提供解决方案。
我想出了一个具有 CountDownLatch 的自定义处理器 bean,我在引导应用程序后对其进行倒计时。因此,在应用程序完全启动并为我工作之前,这些消息将处于空闲状态。
/**
* bootstrap latch processor
*/
@Log4j
class BootstrapLatchProcessor implements Processor
private final CountDownLatch latch = new CountDownLatch(1)
@Override
void process(Exchange exchange) throws Exception
if(latch.count > 0)
log.info "waiting for bootstrapped @ $exchange.fromEndpoint"
latch.await()
exchange.out = exchange.in
/**
* mark the application as bootstrapped
*/
public void setBootstrapped()
latch.countDown()
然后将其用作应用程序中的 bean,并在 Bootstrap.groovy 中调用 setBootstrapped 方法
然后,在您的 RouteBuilder 中,您将处理器放置在您的端点和目的地之间,以便在应用启动之前为您期望消息传入的所有路由:
from("activemq:a.in ").processRef('bootstrapProcessor').to("bean:handlerService?method=handle")
【讨论】:
以上是关于如何延迟spring bean启动?的主要内容,如果未能解决你的问题,请参考以下文章