【问题标题】:@ConfigurationProperties, @Value not Working YET Passing the Tests@ConfigurationProperties,@Value 无法通过测试
【发布时间】:2022-01-09 18:08:17
【问题描述】:

我在阅读配置时遇到了一个奇怪的问题,我见过的解决方案似乎都不起作用。这是我的代码:

@SpringBootApplication
@EnableConfigurationProperties
public class Application {
    
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

这是我的属性类

@Component
@ConfigurationProperties(prefix = "my")
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class MyProperties {
    private String host;
    private int port;
}

然后我使用@Autowired 在我的班级中使用 MyProperties 类:

@Autowired
private MyProperties props;

但是,我的 props 对象为 null。

奇怪的是,这完美地通过了测试

@SpringBootTest
class ApplicationTests {
    
    @Autowired
    private MyProperties props;
    
    @Test
    void test_configuration() {
        Assertions.assertEquals(props.getHost(), "xx.xx.xx.xx");//pass!
        Assertions.assertEquals(props.getPort(), xxxxxx);//pass!
    }
}

它完全拒绝工作,@Value 注入也是如此。我可能会错过什么?

编辑

这是我如何在 MyProperties 上使用 @Autowired 的完整代码(我已包含 @Value,但它也不起作用)

@Slf4j
@Component //also tried @Configurable, @Service
public class MyService {
    
    @Autowired
    private MyProperties props;
    
    @Value("localhost")
    public String host;
    
    public void post() {
        log.info(host + props);// =null and null
    }
}

EDIT2

但是,我注意到在控制器上,它工作得非常好:

@Slf4j
@RestController
@Service
public class Main {
    
    @Autowired
    private MyProperties props;
    
    @Value("localhost")
    private String host;
    
    @GetMapping("/post")
    public void post() {
        log.info(host + props);//=it's perfect!
        new MyService().post();// calling MyService - where @Autowired or @Value is failing
    }
}

【问题讨论】:

  • 你能告诉我们更多关于你在哪里自动装配道具的代码吗?只是为了确保这不是 stackoverflow.com/questions/19896870/… 的重复。
  • @g00glen00b 添加了一些代码;尝试了您共享链接中答案的建议,问题仍然存在。但是,在 RestController 中,它工作得很好。 (并在测试中)
  • 你如何与MyService互动?您能否也显示该代码(您调用myService.post())。
  • @g00glen00b 我在 RestController 示例代码中展示过

标签: spring-boot spring-boot-configuration


【解决方案1】:

这不起作用的原因是因为您使用的 MyService 不是 Spring bean,而是您自己创建的实例(使用 new MyService())。

要完成这项工作,您应该自动装配MyService,而不是创建自己的实例:

@Slf4j
@RestController
public class Main {
    @Autowired // Autowire MyService
    private MyService myService;

    @GetMapping("/post")
    public void post() {
        myService.post(); // Use the myService field
    }
}

有关更多信息,请查看此问答:Why is my Spring @Autowired field null

【讨论】:

  • 就是这样! - 自动装配 MyService。我还在学习春天。你是救生员!
【解决方案2】:

更新:

new MyService() 不是“spring bean”,因此不能与任何东西自动连接!;)

1。龙目岛

有些人使用 Project Lombok 来自动添加 getter 和 setter。 确保 Lombok 不会为此类类型生成任何特定的构造函数,因为容器会自动使用它来实例化对象。

“这种类型”ConfigurationPropertiesExternalized Configuration(我最喜欢的章节之一;)中引用更准确:2.8.1. JavaBean properties binding,在第二个“注意!”的 底部 ;)

所以这可能是一个原因(奇怪的行为)。

【讨论】:

  • 你是对的,new MyService() 不是 Spring bean;我不得不自动接线。也感谢您的参考。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-08
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-26
相关资源
最近更新 更多