【问题标题】:How to implement a resilient bean in Spring?如何在 Spring 中实现弹性 bean?
【发布时间】:2011-07-06 07:22:28
【问题描述】:

我有一个 Spring bean,它通过其构造函数中的 http 访问外部系统。 如果启动时外部系统不可用,则无法创建 bean,应用程序无法正常启动。

我希望无论外部系统如何,我的应用程序都能启动。我宁愿暂时缺少功能,也不愿重新启动应用程序。

我知道这应该可以在 Spring 中通过正确选择范围和代理 bean 工厂来实现,但我不确定实际上是如何做到的。在我看来,Spring AOP 的大部分内容旨在修改已成功创建且无法在创建期间处理异常的目标,还是我错了?

简而言之:我想要一个代理,它在第一次访问时创建目标 bean,然后只要它工作就保留该实例。如果创建失败,它应该抛出异常并在下次调用代理时重试。

那么,您将如何实现此功能?

【问题讨论】:

  • 我不会说 Spring 在这里真的会对你有很大帮助。使用简单的异常处理和状态控制,自己实现弹性可能会更容易。

标签: java spring


【解决方案1】:

你试过懒惰的bean启动吗?

<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>

您不应将此 bean 设置为 Singleton bean 的属性,因为它将在启动时启动它。

【讨论】:

  • 懒惰不会这样做,因为该组件被其他单例使用,所以无论如何它都会在启动时创建
【解决方案2】:

我最终创建了一个 ResilientBeanProxy,它将实际创建推迟到以后,所以是的,它几乎与 Spring 的惰性初始化一样,但增加了它在初始化期间处理异常的特性。例如它不会停止创建应用程序上下文,但在启动期间会发生错误。

如果创建失败,将在下次调用时重试。

【讨论】:

  • 很抱歉,代码早已消失在历史的阴霾中。
【解决方案3】:

考虑一下你的 bean 在构建时是否真的依赖于远程资源?也许您可以在这里简单地使用 lazy init ?您不会在构造函数中调用此外部系统,而是在需要远程资源时首次调用它的方法。如果资源不存在,则使用ResourceUnavailableException 和消息'Try again later'。

【讨论】:

  • 在施工期间有些事情需要处理,如果我推迟到以后,就会到处都是乱七八糟的状态检查代码。
【解决方案4】:

一个旧线程,但我只是试图遵循类似的模式,在我的场景中 Lazy init 有效。

只要 bean 和 注入点(@Autowire 或构造函数参数)都标记为 @Lazy,那么在第一次访问之前不会创建 bean。

如果 bean 创建失败(抛出异常),访问 bean 的组件可以处理异常。但是,由于没有将 bean 的实例添加到上下文中(因为创建失败),bean 的下一次访问将尝试再次创建它。

这似乎在我的上下文中运行良好,其中 bean 是与远程 Web 服务的连接,其 WSDL 在启动时可能不可用。

【讨论】:

    猜你喜欢
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    相关资源
    最近更新 更多