优化@Conditional
parent
86d9800367
commit
9dd99636b9
|
@ -1,25 +1,31 @@
|
||||||
## @Conditional
|
## @Conditional
|
||||||
|
|
||||||
- [@Conditional](#conditional)
|
- [@Conditional](#conditional)
|
||||||
- [一、注解描述](#一注解描述)
|
- [一、基本信息](#一基本信息)
|
||||||
- [二、注解源码](#二注解源码)
|
- [二、注解描述](#二注解描述)
|
||||||
- [三、主要功能](#三主要功能)
|
- [三、注解源码](#三注解源码)
|
||||||
- [四、最佳实践](#四最佳实践)
|
- [四、主要功能](#四主要功能)
|
||||||
- [4.1、在@Bean上使用](#41在bean上使用)
|
- [五、最佳实践](#五最佳实践)
|
||||||
- [4.2、在@Configuration上使用](#42在configuration上使用)
|
- [在@Bean上使用](#在bean上使用)
|
||||||
- [4.3、自定义组合注解](#43自定义组合注解)
|
- [在@Configuration上使用](#在configuration上使用)
|
||||||
- [五、时序图](#五时序图)
|
- [自定义组合注解](#自定义组合注解)
|
||||||
- [六、源码分析](#六源码分析)
|
- [六、时序图](#六时序图)
|
||||||
- [七、注意事项](#七注意事项)
|
- [七、源码分析](#七源码分析)
|
||||||
- [八、总结](#八总结)
|
- [八、注意事项](#八注意事项)
|
||||||
- [8.1、最佳实践总结](#81最佳实践总结)
|
- [九、总结](#九总结)
|
||||||
- [8.2、源码分析总结](#82源码分析总结)
|
- [最佳实践总结](#最佳实践总结)
|
||||||
|
- [源码分析总结](#源码分析总结)
|
||||||
|
|
||||||
### 一、注解描述
|
|
||||||
|
### 一、基本信息
|
||||||
|
|
||||||
|
✒️ **作者** - Lex 📝 **博客** - [我的CSDN](https://blog.csdn.net/duzhuang2399/article/details/133800722) 📚 **文章目录** - [所有文章](https://github.com/xuchengsheng/spring-reading) 🔗 **源码地址** - [@Conditional源码](https://github.com/xuchengsheng/spring-reading/tree/master/spring-annotation/spring-annotation-conditional)
|
||||||
|
|
||||||
|
### 二、注解描述
|
||||||
|
|
||||||
`@Conditional`注解,是用来基于满足某些特定条件来决定一个Bean是否应该被注册到Spring容器的。这提供了一种灵活的方式来根据环境、配置或其他因素来决定是否激活或者创建某个Bean。
|
`@Conditional`注解,是用来基于满足某些特定条件来决定一个Bean是否应该被注册到Spring容器的。这提供了一种灵活的方式来根据环境、配置或其他因素来决定是否激活或者创建某个Bean。
|
||||||
|
|
||||||
### 二、注解源码
|
### 三、注解源码
|
||||||
|
|
||||||
`@Conditional`注解是 Spring 框架自 3.0 版本开始引入的一个核心注解,用于指示一个组件只在所有指定条件匹配时才能被注册。
|
`@Conditional`注解是 Spring 框架自 3.0 版本开始引入的一个核心注解,用于指示一个组件只在所有指定条件匹配时才能被注册。
|
||||||
|
|
||||||
|
@ -60,7 +66,7 @@ public @interface Conditional {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 三、主要功能
|
### 四、主要功能
|
||||||
|
|
||||||
1. **条件化 Bean 注册**
|
1. **条件化 Bean 注册**
|
||||||
+ 可以根据特定的条件来决定是否创建并注册一个 Bean。这允许我们根据环境、配置或其他因素动态地选择哪些 Bean 需要被实例化。
|
+ 可以根据特定的条件来决定是否创建并注册一个 Bean。这允许我们根据环境、配置或其他因素动态地选择哪些 Bean 需要被实例化。
|
||||||
|
@ -75,9 +81,9 @@ public @interface Conditional {
|
||||||
6. **不支持继承**
|
6. **不支持继承**
|
||||||
+ `@Conditional` 注解本身不是继承的,因此,从父类或接口继承的条件不会被子类考虑。
|
+ `@Conditional` 注解本身不是继承的,因此,从父类或接口继承的条件不会被子类考虑。
|
||||||
|
|
||||||
### 四、最佳实践
|
### 五、最佳实践
|
||||||
|
|
||||||
#### 4.1、在@Bean上使用
|
#### 在@Bean上使用
|
||||||
|
|
||||||
首先来看看启动类入口,首先设置一个系统属性`enable.bean`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。
|
首先来看看启动类入口,首先设置一个系统属性`enable.bean`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。
|
||||||
|
|
||||||
|
@ -151,7 +157,7 @@ beanDefinitionName = myBeanConfiguration
|
||||||
beanDefinitionName = user2
|
beanDefinitionName = user2
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 4.2、在@Configuration上使用
|
#### 在@Configuration上使用
|
||||||
|
|
||||||
首先来看看启动类入口,首先设置一个系统属性`enable.config`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。
|
首先来看看启动类入口,首先设置一个系统属性`enable.config`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。
|
||||||
|
|
||||||
|
@ -224,7 +230,7 @@ beanDefinitionName = user4
|
||||||
无任何bean
|
无任何bean
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 4.3、自定义组合注解
|
#### 自定义组合注解
|
||||||
|
|
||||||
首先来看看启动类入口,首先设置一个系统属性`enable.custom`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。
|
首先来看看启动类入口,首先设置一个系统属性`enable.custom`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。
|
||||||
|
|
||||||
|
@ -308,7 +314,7 @@ beanDefinitionName = user6
|
||||||
无任何bean
|
无任何bean
|
||||||
```
|
```
|
||||||
|
|
||||||
### 五、时序图
|
### 六、时序图
|
||||||
|
|
||||||
~~~mermaid
|
~~~mermaid
|
||||||
sequenceDiagram
|
sequenceDiagram
|
||||||
|
@ -330,7 +336,7 @@ ConditionEvaluator->>AnnotatedBeanDefinitionReader:返回true or false
|
||||||
AnnotatedBeanDefinitionReader->>AnnotatedBeanDefinitionReader:如果shouldSkip返回是true,跳过Bean的注册
|
AnnotatedBeanDefinitionReader->>AnnotatedBeanDefinitionReader:如果shouldSkip返回是true,跳过Bean的注册
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
### 六、源码分析
|
### 七、源码分析
|
||||||
|
|
||||||
首先来看看启动类入口,首先设置一个系统属性`enable.custom`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。
|
首先来看看启动类入口,首先设置一个系统属性`enable.custom`为`true`,然后上下文环境使用`AnnotationConfigApplicationContext`(此类是使用Java注解来配置Spring容器的方式),构造参数我们给定了一个`MyConfiguration`组件类,最后打印了Spring上下文中所有的bean定义名称。
|
||||||
|
|
||||||
|
@ -511,7 +517,7 @@ private Condition getCondition(String conditionClassName, @Nullable ClassLoader
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 七、注意事项
|
### 八、注意事项
|
||||||
|
|
||||||
1. **实现 `Condition` 接口**
|
1. **实现 `Condition` 接口**
|
||||||
+ 为了使用 `@Conditional`, 我们需要实现 `Condition` 接口。该接口只有一个方法,`matches(ConditionContext context, AnnotatedTypeMetadata metadata)`,我们需要在这里放置我们的条件逻辑。
|
+ 为了使用 `@Conditional`, 我们需要实现 `Condition` 接口。该接口只有一个方法,`matches(ConditionContext context, AnnotatedTypeMetadata metadata)`,我们需要在这里放置我们的条件逻辑。
|
||||||
|
@ -533,9 +539,9 @@ private Condition getCondition(String conditionClassName, @Nullable ClassLoader
|
||||||
9. **注意与 `@Profile` 的区别**
|
9. **注意与 `@Profile` 的区别**
|
||||||
+ 虽然 `@Conditional` 和 `@Profile` 在某些情况下可以达到相同的效果,但它们的目的不同。`@Profile` 基于环境,而 `@Conditional` 更加通用,允许我们基于任意条件创建 bean。
|
+ 虽然 `@Conditional` 和 `@Profile` 在某些情况下可以达到相同的效果,但它们的目的不同。`@Profile` 基于环境,而 `@Conditional` 更加通用,允许我们基于任意条件创建 bean。
|
||||||
|
|
||||||
### 八、总结
|
### 九、总结
|
||||||
|
|
||||||
#### 8.1、最佳实践总结
|
#### 最佳实践总结
|
||||||
|
|
||||||
1. **基于`@Bean`的条件配置**
|
1. **基于`@Bean`的条件配置**
|
||||||
|
|
||||||
|
@ -567,7 +573,7 @@ private Condition getCondition(String conditionClassName, @Nullable ClassLoader
|
||||||
- 当条件满足(如`enable.custom`为`true`),带有`@ConditionalOnCustomActive`注解的配置类或bean会被注册。
|
- 当条件满足(如`enable.custom`为`true`),带有`@ConditionalOnCustomActive`注解的配置类或bean会被注册。
|
||||||
- 当条件不满足,它们不会被注册。
|
- 当条件不满足,它们不会被注册。
|
||||||
|
|
||||||
#### 8.2、源码分析总结
|
#### 源码分析总结
|
||||||
|
|
||||||
1. **初始化与启动**
|
1. **初始化与启动**
|
||||||
- 通过 `AnnotationConfigApplicationContext` 构造函数初始化 Spring 上下文,并通过 `register` 和 `refresh` 方法完成 bean 的注册和容器的刷新。
|
- 通过 `AnnotationConfigApplicationContext` 构造函数初始化 Spring 上下文,并通过 `register` 和 `refresh` 方法完成 bean 的注册和容器的刷新。
|
||||||
|
|
Loading…
Reference in New Issue