我知道春季启动有很多@Conditional
注释,例如@ConditionalOnBean
,@ConditionalOnClass
,@ConditionalOnProperty
,ConditionalOnWebApplication
。但是我不知道这是如何工作的吗?
例如:
@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>