例如
java
@Configuration
@ConditionalOnClass(LoginUser.class)
public class DataPermissionAutoConfiguration {
@Bean
@ConditionalOnBean(value = { PermissionApi.class, DeptDataPermissionRuleCustomizer.class })
public DeptDataPermissionRule deptDataPermissionRule(PermissionApi permissionApi,
List<DeptDataPermissionRuleCustomizer> customizers) {
DeptDataPermissionRule rule = new DeptDataPermissionRule(permissionApi);
customizers.forEach(customizer -> customizer.customize(rule));
return rule;
}
}
在Spring框架中,通过依赖注入(Dependency Injection,DI)机制,可以自动将符合条件的多个Bean注入到一个集合中。这种特性使得Spring能够自动检测和注入所有符合类型要求的Bean。
来解释你的具体情况:你定义了一个@Bean方法deptDataPermissionRule
,该方法有两个参数:
PermissionApi permissionApi
List<DeptDataPermissionRuleCustomizer> customizers
这里,List<DeptDataPermissionRuleCustomizer> customizers
表示Spring会自动注入所有实现了DeptDataPermissionRuleCustomizer
接口的Bean,并将它们组织到一个List
集合中传递给deptDataPermissionRule
方法。
具体原理
Spring的DI机制在初始化上下文时,会扫描应用程序中的所有Bean定义,并且根据类型匹配的规则进行依赖注入。对于List<DeptDataPermissionRuleCustomizer>
这样的集合类型参数。
Spring会找到所有符合DeptDataPermissionRuleCustomizer
类型的Bean,并将它们注入到这个集合中。
详细步骤
-
扫描和注册Bean:Spring会扫描应用程序上下文并找到所有标记为Bean的类和方法,并将这些Bean注册到Spring的IoC容器中。
-
依赖解析 :当Spring需要创建一个Bean实例时,它会检查该Bean的构造函数和方法参数。如果遇到一个集合类型参数(例如
List<DeptDataPermissionRuleCustomizer>
),Spring会查找所有匹配该集合元素类型的Bean。 -
集合注入 :Spring将所有匹配的Bean放入一个
List
集合中,并将该集合注入到方法参数中。
示例
假设你有以下几个自定义器类:
java
@Component
public class CustomizerA implements DeptDataPermissionRuleCustomizer {
@Override
public void customize(DeptDataPermissionRule rule) {
// Custom logic for A
}
}
@Component
public class CustomizerB implements DeptDataPermissionRuleCustomizer {
@Override
public void customize(DeptDataPermissionRule rule) {
// Custom logic for B
}
}
在这种情况下,Spring会自动将CustomizerA
和CustomizerB
这两个Bean注入到List<DeptDataPermissionRuleCustomizer>
中,并传递给deptDataPermissionRule
方法。
条件注入
你的代码中还使用了@ConditionalOnBean
注解,这表示deptDataPermissionRule
这个Bean的创建是有条件的,它只有在Spring上下文中存在PermissionApi
和至少一个DeptDataPermissionRuleCustomizer
Bean时才会被创建。
总结起来,Spring通过自动化的依赖注入机制,能够自动收集并注入所有符合类型要求的Bean到集合类型参数中,这样你就可以在方法中使用这些Bean了。