【问题标题】:Spring - catch bean creation exceptionSpring - 捕获 bean 创建异常
【发布时间】:2012-11-10 14:15:52
【问题描述】:

我想在我的代码中捕获 bean 实例化异常。我有什么选择? 一种方法是使用基于 Java 的容器配置:

@Configuration
public class AppConfig {
  @Bean
  public SomeBean someBean() {
    try {
      return new SomeBean(); // throws SomeException
    } catch(SomeException se) {
      return new SomeBeanStub();
    }
  }
}

是否可以使用 Spring 使用基于 XML 或基于注释的配置来定义 bean 实例化的异常处理程序?

【问题讨论】:

  • 你找到方法了吗?我想抓住它,杀死进程,而不是让服务器全部加载。我的问题是,如果某些 bean 未正确加载,而其他 bean 加载,则会出现不一致的行为。
  • 非常好的问题:当然,让 Spring-Boot 在初始化阶段管理所有 Bean 非常好,但它们通常在报告失败原因方面做得很糟糕。我喜欢这个问题,但我已经找了多年,找不到答案。好像每个人都认为答案是不必要的。

标签: java spring exception configuration


【解决方案1】:

你不应该这样做。这就是让 Spring 为您创建 bean 的全部意义所在。如果您要使用new(如上)创建自己的 bean,为什么要使用 Spring 为您创建 bean?

您确实可以为自己分配对象并继续工作,而不是依赖注入等等。

虽然我理解问题背后的本质。我认为最好在服务器加载期间失败。原因:应用程序不会处于不一致的状态。假设您捕获了异常并进行了一些清理,但是其他类会期望该 bean 存在而它不存在。

因此最好在初始化时失败,以便应用程序保持一致。虽然我不知道任何其他合法的做法。

【讨论】:

  • 谢谢。问题上下文如下:如果在 bean 的实例化过程中发生了一些不好的事情(数据库故障,另一个外部错误),那么它应该切换到某种维护模式。如果不捕获 bean 创建异常,这是不可能的。您能否详细说明一下包装器如何提供帮助?
  • 这里的问题是,在初始化期间失败的第 3 方 bean 通常很少或根本没有处理报告原因。因此,最好能捕获、确定原因并返回改进的错误。
【解决方案2】:

只是为了完整性。

您还可以延迟初始化 bean 并在第一次使用 bean 时捕获异常。

弹簧配置:

<bean id="a" class="A" lazy-init="true" />

在java中:

import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

public class B {

    @Autowired
    @Lazy
    A a;

    public void foo(){
         try{
               a.foo();
         } catch (BeanCreationException e){
               // ignore if you want
         }
    }
}

【讨论】:

    【解决方案3】:

    方法someBean 应该捕获SomeException,然后以SomeException 作为原因抛出BeanCreationException:

    @Configuration
    public class AppConfig {
      @Bean
      public SomeBean someBean() {
        try {
          return new SomeBean(); // throws SomeException
        } catch (SomeException se) {
          throw new BeanCreationException("someBean", "Failed to create a SomeBean", se);
        }
      }
    }
    

    【讨论】:

      【解决方案4】:

      如果您预计 bean 创建期间会失败,并且 bean 对于应用程序的其余部分不是强制性的(非常合理的情况),您可以按照您的建议通过在 @Bean 方法主体中捕获所有失败异常并返回 @ 987654321@ 表示创建 bean 失败。 在这种情况下,bean 不会被添加到 Spring 应用程序上下文中,如果给定 bean 没有强制依赖项,则上下文构造将成功。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-12
        • 2018-06-26
        相关资源
        最近更新 更多