如何在Spring Boot中以编程方式创建bean?

我有一个应用程序,在application.properties中列出了许多数据源设置。我有一个@ConfigurationProperties可以加载这些设置的类。现在,我想从此类中获取值,ConfigurationProperties并使用它们来动态创建DataSource bean。我尝试使用@PostConstruct和实现BeanFactoryPostProcessor。但是,使用时BeanFactoryPostProcessor,处理似乎发生在早期-在ConfigurationProperties填充我的课程之前。如何DataSource使用Spring Boot" title="Spring Boot">Spring Boot快速读取属性并创建bean?

这是我的application.properties的样子:

ds.clients[0]=client1|jdbc:db2://server/client1

ds.clients[1]=client2,client3|jdbc:db2://server/client2

ds.clients[2]=client4|jdbc:db2://server/client4

ds.clients[3]=client5|jdbc:db2://server/client5

|

还有我的ConfigurationProperties类:

@Component

@ConfigurationProperties(prefix = "ds")

public class DataSourceSettings {

public static Map<String, String> CLIENT_DATASOURCES = new LinkedHashMap<>();

private List<String> clients = new ArrayList<>();

public List<String> getClients() {

return clients;

}

public void setClients(List<String> clients) {

this.clients = clients;

}

@PostConstruct

public void configure() {

for (String client : clients) {

// extract client name

String[] parts = client.split("\\|");

String clientName = parts[0];

String url = parts[1];

// client to datasource mapping

String dsName = url.substring(url.lastIndexOf("/") + 1);

if (clientName.contains(",")) {

// multiple clients with same datasource

String[] clientList = clientName.split(",");

for (String c : clientList) {

CLIENT_DATASOURCES.put(c, dsName);

}

} else {

CLIENT_DATASOURCES.put(clientName, dsName);

}

}

}

在此@PostConstruct方法的结尾,我想BasicDataSource使用这些设置创建一个并将其添加到ApplicationContext。但是,如果我尝试通过实现BeanFactoryPostProcessor和实现来实现postProcessBeanFactory,则该clients属性为null,就像CLIENT_DATASOURCES我填充的一样@PostConstruct

@Override

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

System.out.println("clients: " + CLIENT_DATASOURCES);

}

使用Spring Boot动态创建数据源的最佳方法是什么?

回答:

如何创建你的bean并要求Spring Boot向其中注入值?

就像是

@Bean

@ConfigurationProperties("ds.client1")

public DataSource dataSourceClient1() {

DataSourceBuilder.create().build();

}

@Bean

@ConfigurationProperties("ds.client2")

public DataSource dataSourceClient2() {

DataSourceBuilder.create().build();

}

然后,ds.client1名称空间中的任何设置都属于第一个数据源(即ds.client1.password该数据源的密码DataSource)。

但是,也许你不知道将拥有多少数据源?这变得越来越复杂,尤其是当你需要将那些动态数据源注入其他对象时。如果只需要按名称查找它们,则可以将它们自己注册为单例。这是一个有效的例子

@ConfigurationProperties(prefix = "ds")

public class DataSourceSettings implements BeanFactoryAware {

private List<String> clients = new ArrayList<>();

private BeanFactory beanFactory;

public List<String> getClients() {

return clients;

}

public void setClients(List<String> clients) {

this.clients = clients;

}

@Override

public void setBeanFactory(BeanFactory beanFactory) {

this.beanFactory = beanFactory;

}

@PostConstruct

public void configure() {

Map<String, String> clientDataSources = new HashMap<String, String>();

for (String client : clients) {

// extract client name

String[] parts = client.split("\\|");

String clientName = parts[0];

String url = parts[1];

// client to datasource mapping

String dsName = url.substring(url.lastIndexOf("/") + 1);

if (clientName.contains(",")) {

// multiple clients with same datasource

String[] clientList = clientName.split(",");

for (String c : clientList) {

clientDataSources.put(c, url);

}

}

else {

clientDataSources.put(clientName, url);

}

}

Assert.state(beanFactory instanceof ConfigurableBeanFactory, "wrong bean factory type");

ConfigurableBeanFactory configurableBeanFactory = (ConfigurableBeanFactory) beanFactory;

for (Map.Entry<String, String> entry : clientDataSources.entrySet()) {

DataSource dataSource = createDataSource(entry.getValue());

configurableBeanFactory.registerSingleton(entry.getKey(), dataSource);

}

}

private DataSource createDataSource(String url) {

return DataSourceBuilder.create().url(url).build();

}

}

请注意,这些bean 仅可通过bean名称查找获得。让我知道是否适合你。

以上是 如何在Spring Boot中以编程方式创建bean? 的全部内容, 来源链接: utcz.com/qa/420948.html

回到顶部