Как работает spring -boot @ConditionalOnClass?

Как именно работает аннотация @ConditionalOnClass?

Моя цель - загрузить определенный bean-компонент только в том случае, если в classpath включен jar предоставляющий этот класс.

Я думал, что я мог бы аннотировать @Bean с @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();
}

Теперь любой, имеющий 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]

Так что я, наверное, что-то не так делаю. Как тогда я могу создать бин, условный для jar зависимостей и классов, содержащихся в classpath?

Из весенних документов:

Классы, которые должны присутствовать. Поскольку эта аннотация анализируется при загрузке байт-кода класса, здесь безопасно указывать классы, которых в конечном итоге может не быть в пути к классам.

Но ошибка говорит о другом...

Ответ 1

Хороший улов!

Вы можете использовать на @Bean метода @Bean, но в этом случае вы должны указать свой класс как литерал String:

@Bean
@ConditionalOnClass(name ="de.MyService")
public MyConditionalBean statistics() {
    return new MyConditionalBean();
}

Я уже не помню "почему", но это из существующего кода исходников Spring Boot.