当前位置: 首页 > 知识库问答 >
问题:

使用 Java 配置时,Spring豆定义类名为空

施梓
2023-03-14

我正在实现BeanFactoryPostProcser,我正在尝试提取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配置我的beans时,我毫无问题地获得了类名:

<bean id="arbitraryString" class="java.lang.String"/>

<bean class="com.test.MyFactory"/>

但是,当我使用 JavaConfig 并在那里定义一个 bean(用于演示目的的简单字符串)时,类名将为 null:

@Bean 
public String arbitraryString () {
    return "the bean definition class name will be null";
}

我尝试过搜索这个,无法理解我是否做错了什么,或者这是预期的行为。我在主方法中不执行任何其他操作,而是加载上下文(无论是 XML 还是配置类)。

共有2个答案

古凌
2023-03-14

带有@Bean的Bean由ConfigurationClassBeanDefinitionReader定义,Bean定义类是

所以您可以从它的FactoryMethodMetadata中获取类名

if(beanDefinition instanceof AnnotatedBeanDefinition) { // definition with @Bean Annotation cause this issue
    MethodMetadata factoryMethodMetadata = ((AnnotatedBeanDefinition) beanDefinition).getFactoryMethodMetadata();
    if (factoryMethodMetadata != null) {
        className = factoryMethodMetadata.getReturnTypeName();
    }
}

钱振
2023-03-14

我已经调查了一点,我想我知道问题是什么(不确定我是对的,还是我解释得对)。然而,这似乎是问题所在:

在 JavaConfig 类中定义 Bean 会导致在Spring初始化此类。然而,这里的顺序很重要,我认为:

它将获取您的config类,检索所有@Bean注释的方法,然后创建这些对象。

现在我相信您所指的“root bean”是一个实现类,以防您正在实例化该类。这似乎很自然,但在Spring XML和Spring javaconfig之间需要进行区分。

在xml中:

所有的beans都被定义为类。它们通过调用该类的构造函数来实例化。

在JavaConfig中:

该bean不再是独立的bean。它被当作工厂豆。所以bean并没有真正的根bean类,它有一个工厂bean和一个工厂方法。如何从方法定义中设置根类?您可以将根bean设置为类,但这在大多数类中并不适用。工厂可以返回所返回类的任何实现,因此在创建BeanDefinition对象时,没有可用的根bean。

这可以通过标记您的appconfig静态(工厂方法)来观察。现在,没有工厂bean,因为在扫描配置类时,它没有创建。这意味着,Spring将使用CGI创建一个实现,它是根bean。然而,这不是您所期望的根bean。例如,在我的测试中:

com.*.*.AppConfig$$EnhancerBySpringCGLIB$$1d5cc574

这是我在创建静态bean时得到的输出。

因此,总计:

JavaConfig就像一个工厂,因此在定义形成时创建的bean是未知的。

xml定义良好,显式设置了实现类,因此给出了一个根bean。

需要生成静态bean,因为工厂不存在,但仍需要创建类。

希望有所帮助:)

阿图尔

编辑:最后注意,这是预期行为:)

 类似资料:
  • 当它在. xml文件中定义时,一切都很好。现在我已经开始将. xml文件迁移到java配置。Security.xml是我迁移的第一个文件。 安全xml 已迁移SecurityConfig。JAVA 稍后我将配置,因为我需要首先使当前配置正常工作。运行程序后,我得到以下错误。 每当提供的出现问题时,就会发生此错误。我尝试使用其他一些步骤配置AuthenticationProvided,但都不起作用。

  • 我花了一天的时间想弄清楚,最后不得不求助于stackoverflow寻求专家的建议。 我正在使用java设置spring配置,使其具有两个datasources和两个LocalContainerEntityManagerFactoryBean,如下所示。但Spring默认情况下似乎会寻找entityManagerFactory()和抛出异常(下面包含stacktrace)。我如何配置spring来

  • 我使用java配置来配置Spring Security,并定制了AuthenticationProvider和UserDetailsService,以便在http://forum.Spring.io/forum/spring-projects/Security/95715-extrate-login-fields之后添加额外的登录字段 我很难通过使用java配置将这两个定制类添加到Spring S

  • 我有一个自定义条件类和一个配置,该配置有一个基于自定义条件类(MyCondition)的条件Bean。问题是我需要从上下文中访问另一个bean来评估条件,但是这是失败的,因为“myBean”需要一些其他配置来首先加载。总共有3个单独的配置要加载,在我引入第3个配置类MyConfiguration之前,顺序并不重要。在加载MyConfiguration之前,需要先加载ConfigurationA和C

  • 问题内容: 我有一个Java类,它在启动时基于javassist类加载器创建自定义类加载器,然后运行实际的程序类。我收到以下错误: 该问题与以下事实有关:一个对象是由原始类加载器创建的,而另一个是由自定义类创建的。 有没有办法解决此错误? 在此先感谢 Avner 问题答案: 请尝试将-Dlog4j.ignoreTCL =true设置为希望有帮助。关于log4j的类似问题

  • 本文向大家介绍使用配置类定义Codeigniter全局变量,包括了使用配置类定义Codeigniter全局变量的使用技巧和注意事项,需要的朋友参考一下 CodeIgniter中公共函数不能追加,可以通过 helper 辅助函数实现。 创建 common_helper.php 文件,定义所需公共函数,存放至 application/helpers 目录中。 在 application/config/