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