【问题标题】:Spring Boot - @Configuration class is null in spring componentSpring Boot - Spring 组件中的 @Configuration 类为空
【发布时间】:2019-11-24 14:55:36
【问题描述】:

在配置类上使用 autowired 时,我遇到了 spring boot 的问题。 我通过在 github 上创建一个小的 spring boot project 来最小化这个问题。

我创建了 MyBean 类并将其声明为 @Component 并尝试自动装配声明为 @ 的 MyConf 类配置(并读取文件 myconfig.properties 中的属性)。理论上,一切都在 spring 上下文中,但是当应用程序启动时,MyBean 中的 myConfigProp 变量为 null。

我哪里错了?

我也尝试了以下解决方案,都不起作用:

  • 在 MyBean 中插入 @DependsOn
  • 评论了@Component并将MyBean配置为spring的@Bean

我做的最后一个测试(不在 github 项目上)是在 MyBean 构造函数中将 MyConfigProp 作为参数传递,它成功了。

@Component
public class MyBean {

    String message;

    public MyBean(MyConfigProp myConfigProp) {
        this.message = myConfigProp.getMessage();
    }

}

我有点困惑。

【问题讨论】:

    标签: spring spring-boot autowired


    【解决方案1】:

    看起来您没有将 MyConfigProp 自动装配到 MyBean 中:

    @Component
    public class MyBean {
    
    String message;
    
        @Autowired
        public MyBean(MyConfigProp myConfigProp) {
            this.message = myConfigProp.getMessage();
        }
    
    }
    

    【讨论】:

    • 我们在构建自动加载的时候并不需要@Autowired注解。
    • 这似乎是唯一可行的解​​决方案,但是@Autowired 没有区别。不幸的是,我仍然不明白为什么这是唯一的解决方案
    • @Johna 你说得对,我不知道已经引入了这个功能。更具体地说,自 spring 4.3 以来,您不需要在单参数构造函数上使用 Autowired。然而由于某种原因添加它可以解决问题???
    【解决方案2】:

    您需要在MyBean 类中添加@EnableConfigurationProperties(MyConfigProp.class),使其看起来像:

    MyBean.java

    @Component
    @EnableConfigurationProperties(MyConfigProp.class)
    public class MyBean {
    
    String message;
    
        @Autowired
        public MyBean(MyConfigProp myConfigProp) {
            this.message = myConfigProp.getMessage();
        }
    
    }
    

    MyConfigProp.java

    @PropertySource("classpath:myconfig.properties")
    @ConfigurationProperties(prefix = "config")
    public class MyConfigProp {
    
        private String message;
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    }
    

    【讨论】:

    • @EnableConfigurationProperties(MyConfigProp.class) 没有区别
    • 删除以下行中的@Configurationgithub.com/Hatta84/Spring-Boot-Test/blob/…
    • 没有错。如果您检查了代码,您可以在发布之前对其进行测试。
    • @MichaelW 我检查了代码并对此进行了测试,代码与第一次修改一起使用,添加了@EnableConfigurationProperties(MyConfigProp.class),如上所述。第二个建议是因为我怀疑 Spring 可能对@Configuration 有问题,因为它本质上是一个为上下文生成 Bean 的组件,而这不是生成 Bean,它是绑定属性。
    • @MichaelW 在使用构造函数注入时你也不需要@Autowired,Spring 知道在那个实例中自动装配;)
    【解决方案3】:

    我尝试了所有解决方案,唯一真正解决问题的方法是在 MyBean 构造函数中传递 MyConfigProp 作为参数,就像从帖子中一样,即使没有 @Autowired

    Code update

    @Component
    public class MyBean {
    
      String message;
    
      public MyBean (MyConfigProp myConfigProp) {
         this.message = myConfigProp.getMessage ();
      }
    }
    

    我分享其余的知识。 详细地,尝试提出的解决方案,结果是:

    • @Component stereo-type 上的MyConfigProp 注释添加到 在MyBean 中使用@Autowired 不起作用,甚至添加@ComponentScan。它仍然启动NullPointerException
    • 注释@EnableConfigurationProperties 似乎只有在以下情况下才有用 @Configuration没有用在MyConfigProp上,也没有解决问题

    从测试和文档阅读中,如果我理解正确,问题是我尝试在MyBean 构造函数中使用@ Autowired 中的对象,并且在创建此对象期间,Spring 还没有实例化MyConfigProp,因此是NullPointerException。 我通过添加solutions package 更新了code 以及可能的解决方案:

    • MyBeanWorked:解决方案如上所示。
    • WithoutConstructor:通过将指令移动到方法中, 启动成功,应用程序正常运行。
    • WorkedWithInjectProp:未声明为@Component,但配置为 @Bean。更长一点,但只需要一个属性,也许更干净。

    代码中的更多细节。 我希望我做了一些令人愉快的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-08
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      • 1970-01-01
      • 1970-01-01
      • 2021-03-01
      • 2017-01-07
      相关资源
      最近更新 更多