条件注解
@Conditional
参数是 Condition 数组
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
复制代码
Condition
提供 matches 方法,符合配置条件的返回 true
@FunctionalInterface
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
复制代码
实现一个自定义条件注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnXXXXXCondition.class)
public @interface ConditionalOnXXXXX {
}
public OnXXXXXCondition implements Conditional {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// TODO
}
}
复制代码
Springboot 提供的常用条件注解(org.springframework.boot.autoconfigure.condition
)
批量条件配置
Spring boot 提供了 spring-autoconfigure-metadata.properties
文件来实现批量自动装配条件配置,可以更有效的降低启动时间,原理是类似的
META-INF/spring-autoconfigure-metadata.properties
内容格式:自动配置类的全路径.条件=值
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration.ConditionalOnClass=\ org.influxdb.InfluxDB org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration.AutoConfigureAfter=\ org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration org.springframework.boot.autoconfigure.session.RedisSessionConfiguration.ConditionalOnClass=\ org.springframework.data.redis.core.RedisTemplate,org.springframework.session.data.redis.RedisOperationsSessionRepository
复制代码
自动装配的代码
// 加载 META-INF/spring-autoconfigure-metadata.properties 文件
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
autoConfigurationMetadata, annotationMetadata);
复制代码
protected AutoConfigurationEntry getAutoConfigurationEntry(
AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
// ...
configurations = filter(configurations, autoConfigurationMetadata);
// ..
}
复制代码
private List<String> filter(List<String> configurations,
AutoConfigurationMetadata autoConfigurationMetadata) {
String[] candidates = StringUtils.toStringArray(configurations);
boolean[] skip = new boolean[candidates.length];
boolean skipped = false;
// AutoConfigurationImportFilter 执行 filter
// 实现类:
// OnBeanCondition
// OnClassCondition
// OnWebApplicationCondition
for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {
invokeAwareMethods(filter);
boolean[] match = filter.match(candidates, autoConfigurationMetadata);
for (int i = 0; i < match.length; i++) {
if (!match[i]) {
skip[i] = true;
candidates[i] = null;
skipped = true;
}
}
}
// ...
}
复制代码
评论