Spring Boot 常用注解理解

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 {};
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值