Java研究院 Java研究院

人非生而知之者,知之,而后知不知。

目录
Spring的@Conditional相关注解使用详解
/  

Spring的@Conditional相关注解使用详解

@Conditional注解是Spring 4框架的新特性,该注解使得只有在满足某些特定条件时才启用一些配置。为了更直观的说明用法,我们直接举例子。

准备工作

首先我们准备三个类:ServiceA,ConfigB,ZjoinC。然后为了配合说明演示,记得在启动类中加上打印加载的类信息代码,即:

@Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
        return args -> {
            String[] beanNames = ctx.getBeanDefinitionNames();
            Arrays.sort(beanNames);
            for (String beanName : beanNames) {
                log.info("=========>{}", beanName);
            }
        };
    }

在之前的文章中有提到类加载的内容,不记得或者还不清楚的可以去翻翻看,因为要理解本文需要一些基础知识。我们常用的条件注解一般有两个,即 @ConditionalOnClass@ConditionalOnBean

这两者有什么区别?下面我们来具体具体说明。

@ConditionalOnClass

@ConditionalOnClass 有两个参数:Class<?>[] 和 String[] ,如果我们去看 @ConditionalOnClass 注解的源代码中的注释就会看到对应的说明分别是:

The classes that must be present.

The classes names that must be present.

image.png

意思显而易见,类或者类名称必须存在。但是这里引发一个误解,如果类不存在,直接就编译错误了,还谈什么条件?

比如小老弟举了个类似的例子:

image.png

前文的准备工作中我们并没有ZjoinD类,这个类其实是不存在的,这种情况下编译就通不过了,谈何业务逻辑?

实际上,如果是这样的话,我们应该是用第二个字符数组参数,而不是类数组参数。

在强调一遍,准备工作里打印类加载信息,是因为条件使用是针对类是否被加载到容器中的,也就是上下文中的,所以我们的 ServiceA 需要加上 @Service 注解让 Spring 来管理。

image.png

如上述的代码,启动项目能看到如下输出:

image.png

看到 AService 是应为ServiceA被我重命名了,前面加上A方便排序查看,至于另外的情况看注释后的 √ 和 × 自行测试。

@ConditionalOnBean

有了@ConditionalOnClass为什么还要@ConditionalOnBean?因为针对的是不同的情况。

首先要明白,Bean和Class是两个层面的东西,Bean指的是Spring容器中,实例化了的上下问对象,而class指的是类加载层面能找到这个类信息!

image.png

如上图所示,当我用ConfigB.class作为Bean条件时,ServiceA并没有被加载。

项目能启动成功,说明 ConfigB 是存在的,要不然编译就通不过了,那为什么ServiceA没有被加载?原因在于ConfigB类没有被加载!因为ConfigB的组件注解被注释掉了!

如果在ConfigB上加上@Service或者@Configuration等注解,结果就不一样了。

自己动手试一试吧!!!

总结

@ConditionalOnClass@ConditionalOnBean 都是条件注解,目的是一样的,使用用法不同。会存在两种类型的注解,也是因为我们面对的情况不同。

比如,如果我们的项目运行在Linux平台和Windows平台下有不同的表现,那么我可以在项目启动时针对不同系统实例化不同的对象,然后有不同的实现,这个时候应该用Bean对象是否在上下文中实例化的条件,即 @ConditionalOnBean

如果我们的项目在发布启动时,是动态加载jar包,可能因为版本升级什么的,某些类被废弃了甚至删除了,那我们可以通过灵活使用 @ConditionalOnClass 来实现业务,如果能找到该类,则正常处理业务逻辑。


才疏学浅,难免有坑,有坑也不填
标题:Spring的@Conditional相关注解使用详解
地址:https://studying.icu/articles/2021/11/04/1636008281784.html