gpt4 book ai didi

java - Spring Boot 使用新前缀扩展现有属性类

转载 作者:行者123 更新时间:2023-12-05 05:15:58 30 4
gpt4 key购买 nike

除了标准的DataSourceProperties ("spring.datasource")。

These 2 datasources are not competing (i.e. the app.datasource.alternate properties are not a replacement for the spring.datasource properties) and should live alongside each other in the default application properties.

我希望这样的事情能奏效:

@ConfigurationProperties("app.datasource.alternate")
public class AlternateDataSourceProperties extends DataSourceProperties {}

然而,当我在我的 yaml 中定义属性时:

app:
datasource:
alternate:
schema-username: TEST

然后运行我的测试:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = NONE)
@EnableConfigurationProperties({AlternateDataSourceProperties.class})
public class AlternateDataSourcePropertiesTest {

@Autowired
// @Qualifier("alternateDataSourceProperties")
private AlternateDataSourceProperties props;

@Test
public void propertiesAreInjected() {
assertThat(props.getSchemaUsername()).isEqualTo("TEST");
}
}

当尝试在 DataSourceConfiguration.Tomcat 中创建 datasource bean 时,程序失败并出现 NoUniqueBeanDefinitionException:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Tomcat.class]: Unsatisfied dependency expressed through method 'dataSource' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' available: expected single matching bean but found 2: app.datasource.alternate-com.example.config.AlternateDataSourceProperties,spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' available: \
expected single matching bean but found 2: \
app.datasource.alternate-com.example.config.AlternateDataSourceProperties \
,spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
... 66 more

我不想重写已经存在的整个属性类,我只需要一组不同前缀下的额外属性。这在 Spring Boot 中可能吗?

我正在使用 Spring Boot 1.5.X

更新

从@Prashant 的回答中获得灵感,我尝试创建一个额外的配置文件并注入(inject)以下内容:@PropertySource("classpath:config/alternate-ds.yml")

# alternate-ds.yml
app:
datasource:
alternate:
schema-username: TEST

# AlternateDataSourceProperties.java
@ConfigurationProperties("app.datasource.alternate")
@PropertySource("classpath:config/alternate-ds.yml")
public class AlternateDataSourceProperties extends DataSourceProperties {}

我仍然得到 NoUniqueBeanDefinitionException,因为现在仍然存在竞争的 bean 资源。有没有办法指定一个 bean 不应该被 Autowiring ?

最佳答案

Based on inspiration from @Prashant's answer I have come up with a work around. The solution is somewhat intrusive as it redefines an existing properties bean so could be dangerous, however the @SpringBootTest seem to be ok with this.

An optimal solution for me would be to somehow declare that the custom bean should not be picked up by an autowiring, I have tried adding the autowire = Autowire.NO parameter to the @Bean annotation for the custom property set, but this still gives the NoUniqueBeanDefinitionException.

问题是 spring 在库代码中引用它时不知道要注入(inject)哪个 DataSourceProperties,因为我向应用上下文。我想出的权宜之计是将原始属性定义重新创建为用 @Primary 注释的自定义 @Bean,因此我的自定义 没有歧义DataSourceProperties Bean.

当我需要特殊的数据源属性时,我使用 @Qualifier("alternateDataSourceProperties") 来引用正确的集合。

配置类如下所示:

@Configuration
public class AlternateDataSourcePropertiesConfiguration {
@Bean
@ConfigurationProperties("app.datasource.alternate")
public DataSourceProperties alternateDataSourceProperties() {
return new DataSourceProperties();
}

@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
}

我对它们进行了如下测试:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = NONE, properties={"app.datasource.alternate.schema-username=TEST",
"app.datasource.alternate.username=SOMETHING"})
@ActiveProfiles("test") // there is a default test datasource configured in application-test.properties so I can test that primary configuration is unaffected. i.e. I have a H2 datasource configured here with username 'sa'
public class AlternateDataSourcePropertiesConfigurationTest {

@Autowired
@Qualifier("alternateDataSourceProperties")
private DataSourceProperties alternateDataSourceProperties;

@Autowired
private DataSourceProperties primaryDataSourceProperties;

@Test
public void propertiesAreInjected() {
assertThat(alternateDataSourceProperties.getSchemaUsername()).isEqualTo("TEST");
}

@Test
public void propertiesDontOverridePrimary() {
assertThat(alternateDataSourceProperties.getUsername()).isEqualTo("SOMETHING");
assertThat(primaryDataSourceProperties.getUsername()).isEqualTo("sa");
}
}

关于java - Spring Boot 使用新前缀扩展现有属性类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50959094/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com