spring-boot @ConditionalOnClass如何工作?

mem*_*und 19 java spring spring-boot

@ConditionalOnClass注释究竟如何工作?

我的目标是仅在jar提供此类包含在类路径中时才加载特定的bean .

我认为我可以注释一个@Beanwith @ConditionalOnClass(MyService.class)并将maven中的依赖声明为可选:

<dependency>
    <groupId>de.my</groupId>
    <artifactId>my-framework<artifactId>
    <optional>true</optional>
</dependency>

@Bean
@ConditionalOnClass(MyService.class)
public MyConditionalBean statistics() {
    return new MyConditionalBean();
}
Run Code Online (Sandbox Code Playgroud)

现在,任何具有my-framework依赖性的人都应该自动连接该bean.但是没有依赖的人应该跳过它.

但是当我启动应用程序时,我收到以下错误:

Caused by: java.lang.ClassNotFoundException: de.MyService.class
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1702) ~[catalina.jar:7.0.50]
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547) ~[catalina.jar:7.0.50]
Run Code Online (Sandbox Code Playgroud)

所以我可能做错了什么.然后,我如何在依赖项jar和类路径中包含的类上创建bean条件?

从春季文档:

必须存在的类.由于通过加载类字节码解析此注释,因此可以安全地指定此处可能最终不在类路径上的类.

但错误表明不同......

Art*_*lan 19

接得好!

您可以在@Bean方法级别使用,但在这种情况下,您必须将您的类指定为文字:

@Bean
@ConditionalOnClass(name ="de.MyService")
public MyConditionalBean statistics() {
    return new MyConditionalBean();
}
Run Code Online (Sandbox Code Playgroud)

我不记得已经"为什么",但它来自现有的Spring Boot源代码.

  • 如果你把它放在一个顶级课程中,我将除了在课程加载时拉入课程.那是在使用课程时.将它用作字符串文字可以防止这种情况. (2认同)