0

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

@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对象为空。

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

@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
    }
}

编辑2

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

@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
    }
}
4

2 回答 2

1

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

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

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

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

有关更多信息,请查看此问答:为什么我的 Spring @Autowired 字段为 null

于 2021-12-05T22:05:33.800 回答
0

更新:

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

1. 龙目岛

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

在外部化配置(我最喜欢的章节之一)中ConfigurationProperties提到了“这种类型” ,更确切地说: 2.8.1。JavaBean 属性绑定,在第二个“注意!”的底部 ;)

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

于 2021-12-05T23:39:59.323 回答