Java 如果@Configuration类包含不可解析的类引用,Spring如何调用@Bean方法
Spring可以使用Java 如果@Configuration类包含不可解析的类引用,Spring如何调用@Bean方法,java,spring,spring-boot,classloading,Java,Spring,Spring Boot,Classloading,Spring可以使用ClassReaders解析@Configuration类 假设我们有以下场景 我们有一个具有多个@Bean定义的自动配置类 其中一个@Bean传递了所有条件,而第二个@Bean传递了@ConditionalOnClass&类路径中不存在该类 @配置 类自定义配置{ @豆子 @ConditionalOnClass(String.class) 字符串knownClass(){ 回复“你好”; } @豆子 @ConditionalOnClass(MissingClass.clas
ClassReader
s解析@Configuration
类
假设我们有以下场景
我们有一个具有多个@Bean
定义的自动配置类
其中一个@Bean
传递了所有条件,而第二个@Bean
传递了@ConditionalOnClass
&类路径中不存在该类
@配置
类自定义配置{
@豆子
@ConditionalOnClass(String.class)
字符串knownClass(){
回复“你好”;
}
@豆子
@ConditionalOnClass(MissingClass.class)
缺少类secondBean(){
返回新的MissingClass();
}
}
在这个场景中,我有几个问题
ApplicationContext
@Bean
方法中的断点*自动配置
类加载到JVM中,因为该类将引用在类加载时无法解析的其他类(来自第二个@Bean)@Bean
方法生成类并调用该方法谢谢一般来说,出于这个确切的原因,您应该避免在
@Bean
方法上使用@ConditionalOnClass
。建议使用单独的@配置
类隔离@条件类
条件中介绍了这种情况
要回答您的具体问题:
@Bean
方法中的断点@Bean
方法的主体中使用,则该类应成功加载。如果在@Bean
方法(通常是返回类型)的签名中使用了无法解析的类,则该类将无法加载@Configuration
类和一个类级条件,而不是担心第3节中描述的场景以及什么将起作用和不起作用。对于您的特定示例,如下所示:
@Configuration
class CustomConfiguration {
@Bean
@ConditionalOnClass(String.class)
String knownClass() {
return "Hello";
}
@Configuration
@ConditionalOnClass(MissingClass.class)
static class DoubtfulBeanConfiguration {
@Bean
MissingClass missingClass() {
return new MissingClass();
}
}
}
上面的安迪回答了“如何使用”的问题,即如何使用图书馆。但在这个回答中,我试图回答为什么的问题
这是我的理解
/META-INF/Spring autoconfigure metadata.properties
中读取自动配置文件元数据(在Spring boot autoconfigure
中有一个这样的文件)
- 此文件由基于
@配置的插件生成 下列类别
key 在org.springframework.boot.autoconfigure.EnableAutoConfiguration
文件中,由/META-INF/spring.factories
插件spring boot自动配置处理器
- 生成的文件包含
类级别的注释,例如@Configuration
,@ConditionalOnClass
, e、 [t.c]@AutoConfigureBefore
@Configuration
类的元数据@Configuration
类级条件,包括@ConditionalOnClass
。如果条件成功,它将使用标准java类加载加载@Configuration
类@ConditionalOnClass(MissingClass.class)
保持在@Configuration
级别,那么如果类级别的条件没有计算为true,比如类不在类路径中,spring就不会加载该类@ConditionalOnClass(MissingClass.class)
保持在@Bean
级别,spring将尝试加载@Configuration
类(假设@Configuration
类级别的所有条件都得到满足)&我们将在类加载期间得到NoClassDefFoundError
@ConditionalOnClass
功能给出您的看法,我们将不胜感激
谢谢用一个示例更新了问题我相信我示例中的示例将抛出NoClassDefFound Error是的,它将抛出NoClassDefFound Error。因此,建议不要做你的例子正在做的事情。我添加了一个例子,以及你对问题本身提出的解决方案。若它是正确的,你们能把它加到你们的答案中吗?这样我就可以把它从问题中去掉。谢谢你的帮助!!我已经添加了一个具体的例子,说明事情应该如何组织。