我试图了解我们使用@Configuration
生成的bean如何覆盖默认情况下由SpringBoot生成的bean。我一直致力于一个项目,在很多情况下我们为像ZuulConfigs这样的东西创建bean,并且假设是,无论我们做什么,都应优先于默认生成的bean。我一直试图解决这个问题,但不能。基本上,
非常感谢帮助
答案 0 :(得分:5)
如果某些类在类路径中,则使用Spring AutoConfiguration提供基本配置。
如果要配置spring实例化bean的顺序,可以使用
@DependsOn("A")
public class B {
...
}
这会创建bean“A”,然后是“B”。因此,您可以根据首先需要完成的bean来订购配置。无论如何Spring通过分析bean类自动检测依赖关系。 如需更多帮助,请查看此问题 Spring Boot AutoConfiguration Order
替代方案: 还有“@AutoConfigureOrder”注释(您可以在其中优先配置),您可以查看code以获得更深入的理解。
自动配置的文档是here
答案 1 :(得分:2)
首先,类加载和bean创建是两回事。我们不需要创建一个bean来加载一个类,但是,为了创建一个bean,必须加载一个类。
现在,回到Spring的示例,Spring查看@componentScan
配置的所有包,并创建所有使用@Bean
,@Configuration
和/或{{1}注释的类的bean }}。 Spring的容器跟踪创建的所有bean,因此,当它遇到与默认bean具有相同名称和类型的用户定义bean时,它将用用户定义的bean替换原始定义(例如,我们可以创建自定义@Component
到覆盖Spring引导自己的实例)。如果存在具有相同类的另一个定义(文档here),您还可以使用@ObjectMapper
注释使bean优先。
以下是您的问题的答案:
@Primary
。@Configuration
注释为您的bean提供优先权。您还可以使用@Primary
(here)来定义Bean的创建顺序。@Order
,@Primary
和@Order
annotation,您可以为bean创建自己的层次结构。答案 2 :(得分:2)
请注意:Spring Boot(特别是)自动配置类始终配置。在创建所有用户bean之后。 Spring Boot自动配置类几乎总是使用@ConditionalXXXX
注释来确保应用程序中配置的相同类型/名称和其他条件的任何bean都优先于Spring Boot 自动配置< / em>豆。
答案 3 :(得分:1)
我可以用与我的豆子相似的方式赋予某些优先级
是的。
A)要定义特定的顺序,将处理您的配置类(顺便说一句,不必对配置类进行@Configuration
注释(所谓的完整定义),但足以对其进行注释与@Component
,@ComponentScan
,@Import
,@ImportResource
一起使用,或者只是用@Bean
注释的方法-所谓的lite定义),您应该
1)例如,以这样的主要方法将您的配置候选者添加到SpringApplication
的{{1}}中
primarySource
2)并用SpringApplication.run(
new Class[]{YourSpringBootApplication.class, Config1.class, Config2.class, ...},
args);
注释您的每个配置候选者,@Order
将忽略Ordered
接口,@DependsOn
等的任何其他排序方式,该命令ConfigurationClassPostProcessor
数组中的内容也将被忽略。
然后primarySource
将对您的配置候选进行排序并根据您指定的ConfigurationClassPostProcessor
注释值进行处理。
B)优先级也可以通过定义自己的AutoConfiguration类来实现。尽管配置和自动配置都由相同的@Order
处理,但它们本质上是与众不同的机器。这样做
1)在类路径ConfigurationClassPostProcessor
文件中定义,然后将您的AutoConfiguration类放入该文件的EnableAutoConfiguration部分
/META-INF/spring.factories
2)并使用 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
your.package.AutoConfig1,your.package.AutoConfig2
,@AutoConfigureOrder
或@AutoConfigureAfter
注释注释您的AutoConfiguration类,其他任何排序方式都将被忽略。
就像@Strelok指出的那样,AutoConfiguration类是您自己的,并提供了例如由@AutoConfigureAfter
库提供的,将被添加到“配置候选人”列表的末尾。
但是请记住,配置候选者的顺序将由spring-boot-autoconfigure
处理。不一定与配置类定义的bean的顺序一致将被创建。例如,您可以定义覆盖ConfigurationClassPostProcessor
的Configuration类来对Tomcat Web服务器(如
TomcatServletWebServerFactory
但是,无论您如何定义@Configuration
public class EmbeddedTomcatConfig {
@Bean
public TomcatServletWebServerFactory containerFactory() {
...
return customizedTomcatWebServerFactory;
}
配置类的优先级,该方法都会在Spring Boot应用程序决定创建Web服务器时立即调用。
Spring是否通过某些自定义类加载器实现了这一目标
没有必要。尽管您可以像使用Spring一样为EmbeddedTomcatConfig
定义自己的ClassLoader
,但如果在类路径中可以使用应用程序中配置所需的所有内容,则标准BeanFactory
就足够了。请注意,在第一阶段ClassLoader
不会 load (即不 resolve )配置候选类(否则,{{1中的大多数类}}库将无法加载)。相反,它默认使用字节码分析器ConfigurationClassPostProcessor
分析它们的注释。为此,只需将一个类的二进制形式(字节数组)馈送到字节码分析器就足够了。
答案 4 :(得分:0)
如果要让@Component在春季扫描所有组件时优先于其他@Component,请使用@Order(Ordered.LOWEST_PRECEDENCE),即最大值,以将您的组件加载到其他组件上。
@Primary用于为您的bean提供默认首选项,我们可以使用@Qualifier覆盖默认首选项