SpringBoot回顾(八):让你的注入更加灵活–@

这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战

前言

上一篇给大家介绍了@Valid注解,帮助大家更好的应该繁琐的字段校验场景。这一篇给大家介绍另一个实用的注解@ConditionalOn*。大家在开发的过程中一定遇到过这些场景:当满足一定条件时,我们才去实例化bean;当满足上下文存在时,才去实例化bean;或者说在特性的java版本时我们才去实例化bean。类似上述的场景还有很多,之前我们可能采用的方式就是先把bean统统注入进来,然后通过一些if判断来选择我们需要的对象。相信大家看完本篇以后一定有更多的选择来应对以上的场景。

@Conditional

其实我们在之前用spring框架时,有使用到类似的注解,那就是@Conditional@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。源码如下

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    Class<? extends Condition>[] value();
}
复制代码

我们再看下Condition接口

public interface Condition {
    boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
复制代码

可以看到,我们就是利用matches进行条件匹配,满足就注入,不满足就不执行。
那么我们再来看看Spring Boot下的@ConditionalOn*注解。首先看下Spring Boot中有哪些这样的注解。
image.png
可以看到这里一共提供了13不同场景下的@ConditionalOn*注解供我们使用,下面我们一一简单进行介绍。

@ConditionalOn*

我们将Spring Boot提供的@ConditionalOn*注解整理成表格,方便大家参考使用。

序号 注解名称 使用场景
1 @ConditionalOnBean 仅仅在当前上下文中存在某个对象时,才会实例化一个Bean
2 @ConditionalOnClass 某个class位于类路径上,才会实例化一个Bean
3 @ConditionalOnCloudPlatform 只有运行在指定的云平台上才加载指定的 bean
4 @ConditionalOnExpression 当表达式为true的时候,才会实例化一个Bean
5 @ConditionalOnJava 只有运行指定版本的 Java 才会加载 Bean
6 @ConditionalOnJndi 只有指定的资源通过 JNDI 加载后才加载 bean
7 @ConditionalOnMissionBean 仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean
8 @ConditionalOnMIssionClass 某个class类路径上不存在的时候,才会实例化一个Bean
9 @ConditionalOnNotWebAppilcation 在非 web 环境才加载 bean
10 @ConditionalOnProperty 通过配置文件中的属性值来判定configuration是否被注入
11 @ConditionalOnResource 当要加载的 bean 依赖指定资源是否存在于 classpath 中,那么我们就可以使用这个注解
12 @ConditionalOnSingleCandidate 只有指定类已存在于 BeanFactory 中,并且可以确定单个候选项才会匹配成功
13 @ConditionalOnWebApplication 只有运行在 web 应用里才会加载这个 bean

总结

当然,除了以上提供的13个不同注解,我们还可以使用组合的方式将不用的注解放到一起使用,通过运用条件and、or让我们可以应该更加复杂的场景。