使用JavaConfig时,SpringBean定义类名为null
我正在实现使用JavaConfig时,SpringBean定义类名为null,java,spring,spring-java-config,Java,Spring,Spring Java Config,我正在实现BeanFactoryPostProcessor,并试图提取bean定义类名: @Component public class MyFactory implements BeanFactoryPostProcessor{ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { String[] beanDe
BeanFactoryPostProcessor
,并试图提取bean定义类名:
@Component
public class MyFactory implements BeanFactoryPostProcessor{
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
for (String name : beanDefinitionNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(name);
// 'null' when using JavaConfig, 'java.lang.String' when using XML
System.out.println(beanDefinition.getBeanClassName());
}
}
}
当我通过XML配置Bean时,我可以毫无问题地获得类名:
<bean id="arbitraryString" class="java.lang.String"/>
<bean class="com.test.MyFactory"/>
我尝试过搜索这个,但无法理解我是否做错了什么,或者这是预期的行为。在我的main方法中,除了加载上下文(无论是XML还是config类),我什么也不做。我已经仔细研究了一下,我想我知道问题可能是什么(不确定我是否正确,或者我的解释是否正确)。然而,这似乎是一个问题: 在JavaConfig类中定义bean会导致spring初始化这个类。然而,这里的顺序很重要,我认为: 它将获取您的配置类,检索所有@Bean注释的方法,然后创建这些对象 现在我相信您所指的“根bean”是一个实现类,以防您实例化该类。这看起来很自然,但SpringXML和SpringJavaConfig之间有一个目标 在xml中: 所有bean都定义为类。它们通过调用该类的构造函数来实例化 在JavaConfig中: bean不再是一个独立的bean。它被当作工厂生产的豆子。因此bean实际上没有根bean类,它有一个工厂bean和一个工厂方法。如何从方法定义中设置根类?您可以将根bean设置为类,但这在大多数类中并不成立。工厂可以返回返回的类的任何实现,因此在创建BeanDefinition对象时,没有可用的根bean 这可以通过将appconfig标记为static(工厂方法)来观察。现在,没有工厂bean,因为在扫描配置类时,它没有被创建。这意味着spring将使用CGI创建一个实现,即根bean。然而,这不是您所期望的根bean。例如,在我的测试中:
com.*.*.AppConfig$$EnhancerBySpringCGLIB$$1d5cc574
这是我在创建静态bean时得到的输出
因此,总的来说:
JavaConfig的作用类似于一个工厂,因此创建的bean在定义形成时是未知的
Xml定义良好,显式设置了实现类,因此给出了根bean
需要生成静态bean,因为工厂不存在,但仍然需要创建类
我希望这有帮助:)
--阿图尔
编辑:最后一点注意,它的预期行为:)带有
@Bean
的Bean由ConfigurationClassBeanDefinitionReader
和Bean定义
定义类是AnnotatedBeanDefinition
所以。您可以从它的FactoryMethodMetadata
if(beanDefinition instanceof AnnotatedBeanDefinition) { // definition with @Bean Annotation cause this issue
MethodMetadata factoryMethodMetadata = ((AnnotatedBeanDefinition) beanDefinition).getFactoryMethodMetadata();
if (factoryMethodMetadata != null) {
className = factoryMethodMetadata.getReturnTypeName();
}
}
您是否尝试在注释中提供Bean名称
@Bean(name=“arbirystring”)
的可能重复:这似乎是意料之中的behaviour@MichaelMurray刚刚尝试过,仍然为空。@pandadb这不是重复的,我确实发现了这个问题,但它没有解决在本例中使用JavaConfig和xml之间的区别。需要通过调用构造函数来创建配置。因此,很清楚实现bean是什么,因此(通过CGI增强)类是根bean。在我的例子中:appConfig:Root bean:class[com.*.*.appConfig$$EnhancerBySpringCGLIB$$1d5cc574]
if(beanDefinition instanceof AnnotatedBeanDefinition) { // definition with @Bean Annotation cause this issue
MethodMetadata factoryMethodMetadata = ((AnnotatedBeanDefinition) beanDefinition).getFactoryMethodMetadata();
if (factoryMethodMetadata != null) {
className = factoryMethodMetadata.getReturnTypeName();
}
}