2017-09-14 105 views
6

我知道Spring Boot有很多@Conditional注释,例如@ConditionalOnBean@ConditionalOnClass,@ConditionalOnProperty,ConditionalOnWebApplication。但我不知道这是如何工作的?条件注释如何在Spring Boot中起作用?

例如:

@Configuration  
@ConditionalOnClass(MyBean.class) 
public class MyConfiguration{ 
    // omitted  
} 

我了解,MyConfiguration将只有MyBean在我的类路径被加载。但是,如果MyBean类不在我的类路径中,编译器达到@ConditionalOnClass(MyBean.class)一行,它将如何编译和运行,是否会抛出编译器错误?只要我在eclipse中添加这样的代码,我就会收到编译时错误。对不起,如果这是太基本的问题,但我不知道我错过了什么理解。

回答

6

春天引导被编译,有很多可选的依赖关系;所以当编译Spring Boot时,MyBean.class位于类路径中。

现在,您的应用程序在其类路径中可能没有MyBean.class,但它在运行时不会失败。这是因为处理@ConditionalOnClass注释的基础结构实际上会读取配置的字节码,并且只会在该MyBean.class存在时才加载它们。见@ConditionalOnClass javadoc

现在自动配置是一个广泛的主题,你可以学习more about this in this talk

+0

您的解释和链接非常有帮助。非常感谢 –

0

您通常使用Optional依赖关系:

<dependency> 
    <groupId>org.freemarker</groupId> 
    <artifactId>freemarker</artifactId> 
    <optional>true</optional> 
</dependency> 
1

作为Spring Boot Documentation说:

的@ConditionalOnClass和@ConditionalOnMissingClass注解 允许基于存在或特定类的不存在 被包括配置。由于使用ASM解析注释元数据 的事实,您实际上可以使用value属性来引用 真实类,即使该类可能实际上并不出现在正在运行的应用程序类路径的 上。如果您希望使用字符串值指定类名称,也可以使用名称属性 。

因此,他们使用字节码操作库ASM能够在运行时分析类名,即使这些类不再在类路径中。由于Spring是开源的,你甚至可以去看看annotation reading code