文章目录
Condition
只有当对应的条件匹配的时候才注册组件
@FunctionalInterface
public interface Condition {
// ConditionContext持有beanFactory、Environment、加载器等资源
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
ConfigurationCondition
在Condition的基础上提供类的解析阶段,PARSE_CONFIGURATION表示在配置类解析的时候执行过滤,REGISTER_BEAN表示在解析bean实例时过滤。
public interface ConfigurationCondition extends Condition {
ConfigurationPhase getConfigurationPhase();
enum ConfigurationPhase {
PARSE_CONFIGURATION,
REGISTER_BEAN
}
}
@Conditional
只有当value值中的条件匹配时,组件才会注册
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
// 需满足的条件集合
Class<? extends Condition>[] value();
}
要理解Spring boot的条件注解首先要理解SpringBootCondition,该类是Spring boot中所有条件类的父类,提供合理的日志记录以帮助用户诊断加载了哪些类。
SpringBootCondition
public abstract class SpringBootCondition implements Condition {
// 日志记录
private final Log logger = LogFactory.getLog(getClass());
// 匹配方法
public final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 获得注解上的类或方法名
String classOrMethodName = getClassOrMethodName(metadata);
try {
// 调用子类的getMatchOutcome方法获得匹配结果
ConditionOutcome outcome = getMatchOutcome(context, metadata);
// 日志打印
logOutcome(classOrMethodName, outcome);
// 记录
recordEvaluation(context, classOrMethodName, outcome);
// 返回匹配结果
return outcome.isMatch();
}
···异常抛出
}
}
以下说明在@EnableAutoConfiguration注解中默认的过滤注解
@ConditionalOnBean
当BeanFactory中存在指定的bean时才注入注释的类
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class)
public @interface ConditionalOnBean {
// 根据bean的类型
Class<?>[] value() default {};
String[] type() default {};
// 根据bean的名称
String[] name() default {};
// 根据bean上的注解
Class<? extends Annotation>[] annotation() default {};
}
@ConditionalOnClass
调用类加载器加载当前路径下的类,存在才注入类。
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass {
Class<?>[] value() default {};
String[] name() default {};
}
@ConditionalOnWebApplication
只有当前程序为web应用时才导入类
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnWebApplicationCondition.class)
public @interface ConditionalOnWebApplication {
// web类型,默认ANY
Type type() default Type.ANY;
}
@ConfigurationProperties
当一个类需要注入多个@Value变量会显得繁琐,通过该注解实现统一前缀属性匹配类字段完成注入。
- 注入类的字段名需与属性名匹配(宽泛)
- 类的字段必须有setter方法
- 通过ConfigurationPropertiesBindingPostProcessor在类初始化时完成注入
- ignoreInvalidFields控制忽略无效字段的注入,防止启动报错
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConfigurationProperties {
// 前缀
@AliasFor("prefix")
String value() default "";
@AliasFor("value")
String prefix() default "";
}
@EnableConfigurationProperties
使@ConfigurationProperties修饰的类无需@component注解就能导入到IOC容器中
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({EnableConfigurationPropertiesImportSelector.class})
public @interface EnableConfigurationProperties {
// 需要导入配置属性类
Class<?>[] value() default {};
}
@AutoConfigAfter
控制配置类加载顺序,当前类在value中定义的类之后加载,只针对META-INF/spring.factories下定义的配置类
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface AutoConfigureAfter {
// 在定义的类之后加载
Class<?>[] value() default {};
String[] name() default {};
}
@AutoConfigBefore
控制配置类加载顺序,当前类在value中定义的类之前加载
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface AutoConfigureBefore {
// 在定义的类之前加载
Class<?>[] value() default {};
String[] name() default {};
}