如何使用 Java 配置覆盖 spring beans
How to override spring beans with Java config
我在尝试覆盖 spring zuul 中定义的 RibbonRoutingFilter bean 时遇到了这个问题。强调一下,我正在做一个覆盖,而不仅仅是创建一个相同类型的 bean。所以一天结束时,我希望 zuul 的 "ribbonRoutingFilter" bean 根本没有注册。
所以我有自己的实现。我尝试的第一件事是使用@component 注释并自动装配依赖项。在构造函数中添加了一个断点,它最终从未被调用。所以我意识到我的定义必须比 zuul 的更早加载。因此,我使用@Configuration 注释和@Order(Ordered.HIGHEST_PRECEDENCE)
创建了一个配置class,并使用@Bean 注释在其中实例化我的class。不过,我的方法总是提前加载。
事实证明,在加载配置 classes 定义时遵循特定顺序 Spring,这就是覆盖发生的地方。 Class org.springframework.context.annotation.ConfigurationClassParser 在方法doProcessConfigurationClass()中有详细的逻辑。我将把我的简化总结或排序规则放在这里:
- 如果您的应用程序 class(其中定义了 main() 方法)在其中定义了任何 classes,它们将被解析并首先注册其中的定义
- 然后它将注册定义为@component 并定义在@Configuration class
中的Bean
- 然后它将添加由@Import
引入的定义
- 然后它将添加由@ImportResource
引入的定义
- 然后在应用程序中添加来自@bean 方法的定义class
- 然后从接口的默认方法(我认为是 java 8)
- 然后尝试对任何 parent class 应用程序 class 扩展执行上述相同步骤。
这解释了为什么我的覆盖不起作用。这是因为我一直在尝试在第 2 步中进行尝试。但是 zuul 通过第 3 步中的 @Import 定义了 bean。
所以为了解决我的问题,我在我的应用程序 class 中添加了一个 @Bean 注释方法,并按预期进行了实例化和覆盖。
以上总结可能并不准确,它只是让您了解可能导致覆盖失败的原因。您最好在尝试特定用例时调试 ConfigurationClassParser。
我在尝试覆盖 spring zuul 中定义的 RibbonRoutingFilter bean 时遇到了这个问题。强调一下,我正在做一个覆盖,而不仅仅是创建一个相同类型的 bean。所以一天结束时,我希望 zuul 的 "ribbonRoutingFilter" bean 根本没有注册。
所以我有自己的实现。我尝试的第一件事是使用@component 注释并自动装配依赖项。在构造函数中添加了一个断点,它最终从未被调用。所以我意识到我的定义必须比 zuul 的更早加载。因此,我使用@Configuration 注释和@Order(Ordered.HIGHEST_PRECEDENCE)
创建了一个配置class,并使用@Bean 注释在其中实例化我的class。不过,我的方法总是提前加载。
事实证明,在加载配置 classes 定义时遵循特定顺序 Spring,这就是覆盖发生的地方。 Class org.springframework.context.annotation.ConfigurationClassParser 在方法doProcessConfigurationClass()中有详细的逻辑。我将把我的简化总结或排序规则放在这里:
- 如果您的应用程序 class(其中定义了 main() 方法)在其中定义了任何 classes,它们将被解析并首先注册其中的定义
- 然后它将注册定义为@component 并定义在@Configuration class 中的Bean
- 然后它将添加由@Import 引入的定义
- 然后它将添加由@ImportResource 引入的定义
- 然后在应用程序中添加来自@bean 方法的定义class
- 然后从接口的默认方法(我认为是 java 8)
- 然后尝试对任何 parent class 应用程序 class 扩展执行上述相同步骤。
这解释了为什么我的覆盖不起作用。这是因为我一直在尝试在第 2 步中进行尝试。但是 zuul 通过第 3 步中的 @Import 定义了 bean。
所以为了解决我的问题,我在我的应用程序 class 中添加了一个 @Bean 注释方法,并按预期进行了实例化和覆盖。
以上总结可能并不准确,它只是让您了解可能导致覆盖失败的原因。您最好在尝试特定用例时调试 ConfigurationClassParser。