【问题标题】:Is there a way to prevent bean overriding with Spring Boot?有没有办法防止 Spring Boot 覆盖 bean?
【发布时间】:2016-12-12 04:15:54
【问题描述】:

使用 Spring 的 AbstractRefreshableApplicationContext,如果 Bean ID 或循环引用发生冲突,我可以通过设置几个标志并刷新上下文来强制 Spring 失败:

AbstractRefreshableApplicationContext refreshableContext;
...
refreshableContext.setAllowBeanDefinitionOverriding(false);
refreshableContext.setAllowCircularReferences(false);
refreshableContext.refresh();

但是,Spring Boot 返回一个ConfigurableApplicationContext,它不是 AbstractRefreshableApplicationContext 的实例,并且似乎没有任何方法来防止 bean 定义覆盖或循环引用。

有没有人知道一种方法并举例说明如何防止这些类型的冲突?

就上下文而言,这是一个混合了带注释和 xml 定义的 bean 的大型项目。使用的 Spring Boot 版本是 1.3.1.RELEASE。在某些情况下,人们在 xml 中添加了重复的 bean 定义,但应用程序启动良好,并且在运行时问题开始发生之前,原始 bean 被覆盖并不会立即显现出来。

这里的目标是防止应用程序在发生此类冲突时启动事件。从各种论坛我知道 Spring IDE 可以检测到这些,但希望在 CI 构建中强制执行这一点,这是一个更强大的安全网。

经过一番搜索,我在 Sprint Boot 返回的上下文中找不到对此的任何支持。如果这不能通过上下文来完成,是否有不同的解决方案可用?

提前致谢。

【问题讨论】:

  • @Primary 是你的朋友。和 /@Resource... 主要和资源 -_-
  • 感谢您的建议,但无论 bean 来自 xml 还是 java,我认为这不会在应用程序上下文中起作用。当我回到我的办公桌时,我会阅读 Javadocs 以供那些人查看。
  • 无论它来自哪里,它都会通过 id 捕获 bean。主要也是第一个。
  • 好的,你试过投射吗? Spring 返回的是 AbstractRefreshableApplicationContext 确实实现的接口,所以它可能是同一个对象

标签: java spring spring-boot


【解决方案1】:

您可以在构建 Spring Boot 应用程序时使用初始化程序:

@SpringBootApplication
public class SpringBootApp {

    public static void main(String... args) {
        new SpringApplicationBuilder(SpringBootApp.class)
            .initializers(new ApplicationContextInitializer<GenericApplicationContext>() {
                @Override
                public void initialize(GenericApplicationContext applicationContext) {
                    applicationContext.setAllowBeanDefinitionOverriding(false);
                }
            })
        .run(args);

    }
}

或者使用 java 8:

new SpringApplicationBuilder(SpringBootApp.class)
    .initializers((GenericApplicationContext c) -> c.setAllowBeanDefinitionOverriding(false) )
    .run(args);

【讨论】:

  • 这个实现看起来就像我正在寻找的那样。尝试一下,如果一切正常,这将是一个接受的答案,并获得赞成票。
  • 这个解决方案有效,我已经能够在我的 Spring Boot 应用程序中成功解决定义冲突。感谢您的回答。附带说明一下,当禁用 bean 定义覆盖时,现在似乎来自 Spring Boot 嵌入式 Web 应用程序上下文的故障。我现在将进一步深入研究这个新问题,并且可能在不久的将来某个时候就这个新问题提出一个新问题。
  • 您是否发现第二个故障来自 Spring Boot 嵌入式 Web 应用程序上下文?我有同样的问题。
【解决方案2】:

将以下内容添加到您的 application.yml 中

spring.main.allow-bean-definition-overriding: false

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 2021-07-25
    • 2021-02-14
    • 2013-04-05
    • 2019-04-07
    • 2019-02-15
    • 2018-10-05
    相关资源
    最近更新 更多