【问题标题】:Why can't I inject one of my PoJo's with Spring's @Value annotation?为什么我不能用 Spring 的 @Value 注释注入我的 PoJo 之一?
【发布时间】:2021-10-27 19:35:20
【问题描述】:

在 Spring 中,我可以使用 @Value 注入配置各种对象,如 int、boolean、String 等。 我什至可以通过一次@Value 注入来配置整个地图结构。

假设我们有以下 TCP 服务器规范类:

public class TcpServerSpec {

    private boolean enabled;
    private String host;
    private int port;

    /* getters & setters */
}

我可以通过它们的名称注入几个服务器规范的映射,这样做......

@Value("${com.harry.potter.sockets}")
private HashMap<String, TcpServerSpec> sockets;

...具有以下 YAML 配置 (application-test1.yml):

com:
  harry:
    potter:
      sockets:
        server1:
          enabled: true
          host: host1
          port: 1111
        server2:
          enabled: true
          host: host2
          port: 2222

但通常需要介于两者之间:只注入一个 TcpServerSpec:

@Value("${com.harry.potter.sockets.server1}")
private TcpServerSpec server1;

然后我可以成功通过以下测试:

@RunWith(SpringRunner.class)
@SpringBootTest
@ConfigurationProperties("com.harry.potter.sockets")
@TestPropertySource(locations = "classpath:application-test1.yml")
public class MyServerConfiguration1Test {

    @Value("${com.harry.potter.sockets.server1}")
    private TcpServerSpec server1;

    @Value("${com.harry.potter.sockets.server2}")
    private TcpServerSpec server2;

    @Test
    public void testServer1Spec() {
        Assert.assertTrue(server1.isEnabled());
        Assert.assertThat(server1.getHost(), is("host1"));
        Assert.assertThat(server1.getPort(), is(1111));
    }

    @Test
    public void testServer2Spec() {
        Assert.assertTrue(server2.isEnabled());
        Assert.assertThat(server2.getHost(), is("host2"));
        Assert.assertThat(server2.getPort(), is(2222));
    }
}

为什么这不可能? 还是这样?

【问题讨论】:

  • 经过一些测试,我确实认为注入地图比简单地使用@Value 注释要复杂一些。

标签: java spring dependency-injection


【解决方案1】:

你想要的不是@Value,而是@ConfigurationProperties

您可以像这样手动声明您的 bean:

@Configuration
class BeanConfig {
  
  @Bean
  @ConfigurationProperties(prefix = "com.harry.potter.sockets.server1")
  public TcpServerSpec server1() {
    return new TcpServerSpec();
  }

  @Bean
  @ConfigurationProperties(prefix = "com.harry.potter.sockets.server2")
  public TcpServerSpec server2() {
    return new TcpServerSpec();
  }
}

然后用@Qualifier("server1") 和@Qualifier("server2") 注入这些bean。

【讨论】:

  • 你为什么有@Bean @ConfigurationProperties?为什么prefix?我不明白这是如何回答问题的
  • 你说得对,使用@ConfigurationProperties时不需要@Bean
  • 检查您的答案后:我认为需要 \@Bean 注释,但不需要 \@Qualifier。发现这两个托管 bean 没有任何解析问题,因为它们的名称不同 serer1/server2。
  • 伟大的@JBStonehenge !回滚 Bean 注解 呵呵 我的回答对你有帮助吗?
  • 感谢您的回答。它帮助了我,但也提出了另一个问题。添加 server3 需要在 yaml 文件中进行配置更改,并在 BeanConfig 类中进行编程更改。
猜你喜欢
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 2015-06-14
  • 1970-01-01
  • 2016-10-17
  • 1970-01-01
  • 2014-04-06
  • 2015-02-15
相关资源
最近更新 更多