条件注释如何在春季启动中起作用



我知道春季启动有很多@Conditional注释,例如@ConditionalOnBean@ConditionalOnClass@ConditionalOnPropertyConditionalOnWebApplication。但是我不知道这是如何工作的吗?

例如:

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

我所理解的是,只有在我的类路径中可用的MyBean时,MyConfiguration才会加载。但是,如果MyBean类不在我的类路径中时,它将如何编译和运行,因为编译器到达@ConditionalOnClass(MyBean.class)行,它不会抛出编译器错误?一旦我在Eclipse中添加此类代码,我就会收到编译时间错误。抱歉,如果这太基本的问题,但我不知道我缺少什么理解。

春季启动正在编译许多可选依赖性;因此,当编译弹簧启动时,MyBean.class在classPath上。

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

现在自动配置是一个广泛的主题,您可以在本演讲中了解更多有关此的主题。

正如春季启动文档所说:

@conditionalonclass和@conditionalonmissingclass注释 允许根据存在或不存在的配置包含配置 特定类。由于注释元数据是 使用ASM解析您实际上可以使用值属性来参考 即使该课程实际上可能没有出现 运行的应用程序类路径。您也可以使用名称属性 如果您喜欢使用字符串值指定类名。

因此,他们使用字节码操纵库ASM能够在运行时解析类名,即使这些类不再在类路径上。由于春季是开源的,您甚至可以去看注释读取代码。

您通常会使用Optional依赖项:

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

最新更新