1、@ConditionalOnClass通常与@Configuration 结合使用,意思是当classpath中存在某类时满足条件
2、那么问题来了,当我本地使用这个注解的时候
编译不通过
3、然而 KafkaAutoConfiguration 这个类为什么能正常编译通过呢,它也在报红
4、我们到引用的spring boot pom文件中看一下
首先我们工程引用的是
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
进入 发现 引用了
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.1.5.RELEASE</version>
<scope>compile</scope>
</dependency>
再进入 发现引用了
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.5.RELEASE</version>
<scope>compile</scope>
</dependency>
再进入 发现引用了
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<version>2.2.6.RELEASE</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
那么问题就出现在这个<optional>true</optional>
KafkaAutoConfiguration引入了这个包,所以可以通过编译,但是optional设为了true,依赖不会传递到我们的工程,所以我们使用时会找不到KafkaTemplate.class这个文件,编译时会报错。
5、我们报错的问题找到原因了,那么问题又来了,
为什么KafkaAutoConfiguration在我们工程里没引用kafka却不会报错呢
因为!KafkaAutoConfiguration是.class文件,已经编译好了,不会再次编译了!!
小知识:
一个Java文件从编码完成到最终执行,一般主要包括两个过程
- 编译
- 运行
编译,即把我们写好的java文件,通过javac命令编译成字节码,也就是我们常说的.class文件。
运行,则是把编译生成的.class文件交给Java虚拟机(JVM)执行
6、所以 我们不引用kafka相关jar包却还想模拟相关操作怎么办呢
用类的 所在包路径 + 类名 当参数即可
@Bean
@ConditionalOnClass(name = "org.springframework.kafka.core.KafkaTemplate")
//@ConditionalOnMissingClass(value = "org.springframework.kafka.core.KafkaTemplate")
public AutowiredDemo autowiredDemo() {
System.out.println("准备初始化AutowiredDemo");
return new AutowiredDemo();
}
成功运行
未引入
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
时,没有初始化
引入后
控制台输出
准备初始化AutowiredDemo