java - 在非托管 @Bean 上使用 @ConfigurationProperties
问题描述
我想从@ConfigurationProperties
出色的设施中受益,而无需将 bean 暴露在我的上下文中。这不是@Primaries
诸如此类的问题,我根本无法将另一个暴露Datasource
在上下文中。我怎样才能实现以下目标?
@ConfigurationProperties("com.non.exposed.datasource.hikari")
public DataSource privateHikariDatasource() {
if (Objects.isNull(this.nonExposedDatasource)) {
this.nonExposedDatasource = this.nonExposedDatasourceProperties.initializeDataSourceBuilder().build();
}
return this.nonExposedDatasource;
}
感谢@LppEdd的回答,最终完美的解决方案是:
@Autowired
private Environment environment;
public DataSource privateHikariDatasource() {
if (Objects.isNull(this.nonExposedDatasource)) {
this.nonExposedDatasource = bindHikariProperties(this.nonExposedDatasourceProperties.initializeDataSourceBuilder().build());
}
return this.nonExposedDatasource;
}
//This does exactly the same as @ConfigurationProperties("com.non.exposed.hikari") but without requiring the exposure of the Datasource in the ctx as @Bean
private <T extends DataSource> T bindHikariProperties(final T instance) {
return Binder.get(this.environment).bind("com.non.exposed.datasource.hikari", Bindable.ofInstance(instance)).get();
}
然后您可以在内部调用您的 beanthis.privateHikariDatasource()
以供其他 bean 使用。非常感谢@LppEdd!
解决方案
由于这DataSource
是类私有的,并且包含类可以/在 Spring 上下文中,因此您可以拥有一个@ConfigurationProperties
类
@ConfigurationProperties("com.foo.bar.datasource.hikari")
public class HikariConfiguration { ... }
哪个,通过注册它@EnableConfigurationProperties
,可用于自动装配
@EnableConfigurationProperties(HikariConfiguration.class)
@SpringBootApplication
public class Application { ... }
因此可以在包含类中自动装配
@Component
class MyClass {
private final HikariConfiguration hikariConfiguration;
private DataSource springDatasource;
MyClass(final HikariConfiguration hikariConfiguration) {
this.hikariConfiguration = hikariConfiguration;
}
...
private DataSource privateSingletonDataSource() {
if (Objects.isNull(this.springDatasource)) {
this.springDatasource = buildDataSource(this.hikariConfiguration);
}
return this.springDatasource;
}
}
buildDataSource
将手动构建DataSource
实例。
请记住,在构建DataSource
.
最后的回应是你不能重复使用DataSourceProperties
. 你甚至不能扩展它来改变属性的前缀。上下文中只能存在它的一个实例。
你能做的最好的就是模仿 Spring 所做的事情。
有
com.non.exposed.datasource.hikari.url=testUrl
com.non.exposed.datasource.hikari.username=testUsername
com.non.exposed.datasource.hikari.password=testPassword
...
您可以定义一个新@ConfigurationProperties
类
@ConfigurationProperties("com.non.exposed.datasource")
public class NonExposedProperties {
private final Map<String, String> hikari = new HashMap<>(8);
public Map<String, String> getHikari() {
return hikari;
}
}
@Configuration
然后,在你的/类中自动装配这个属性@Component
类。
遵循代码内注释。
@Configuration
public class CustomConfiguration {
private final NonExposedProperties nonExposedProperties;
private DataSource dataSource;
CustomConfiguration(final NonExposedProperties nonExposedProperties) {
this.nonExposedProperties= nonExposedProperties;
}
public DataSource dataSource() {
if (Objects.isNull(dataSource)) {
// Create a standalone instance of DataSourceProperties
final DataSourceProperties dataSourceProperties = new DataSourceProperties();
// Use the NonExposedProperties "hikari" Map as properties' source. It will be
// {
// url -> testUrl
// username -> testUsername
// password -> testPassword
// ... other properties
// }
final ConfigurationPropertySource source = new MapConfigurationPropertySource(nonExposedProperties.getHikari());
// Bind those properties to the DataSourceProperties instance
final BindResult<DataSourceProperties> binded =
new Binder(source).bind(
ConfigurationPropertyName.EMPTY,
Bindable.ofInstance(dataSourceProperties)
);
// Retrieve the binded instance (it's not a new one, it's the same as before)
dataSource = binded.get().initializeDataSourceBuilder().build();
}
// Return the constructed HikariDataSource
return dataSource;
}
}
推荐阅读
- php - 使用 XAMPP 服务器在 ubuntu 16.04 LTS 上安装 Phalcon
- ffmpeg - Audacity 中的 ffmpeg 输出
- windows - PostgreSQL安装总是卡在最后一步
- powershell - 如何使用 folder.copyHere() 方法在 PowerShell 中使用 Windows.Forms.OpenDialog 中的多选进行复制?
- android - Picasso 2.71828 加载 uri 问题
- php - SimpleXML 按索引删除多个节点
- javascript - 等待高程服务请求回调
- java - 如何在 JList 中显示 File[] 数组
- android - Android NDK - 如何解析 K&R 风格的函数声明
- javascript - 为什么 Array(3) 创建的数组没有索引 0、1、2?