我怎样才能在春天拥有一个不是 bean 的数据源对象?

Posted

技术标签:

【中文标题】我怎样才能在春天拥有一个不是 bean 的数据源对象?【英文标题】:how can I have a datasource object that is not a bean in spring? 【发布时间】:2016-11-25 11:45:58 【问题描述】:

这听起来可能很奇怪。但我想知道如何/是否可以在运行时而不是在容器启动时创建数据源对象。

这是我正在解决的问题:

我有一个 mysql 数据库,它存储我需要连接并进行夜间处理的其他 SQL Server 的 URL、用户名和密码。此 SQL Server 列表每次都会更改。所以它不能在属性文件中硬编码。此外,SQL 服务器的数量约为 5000 或更多。

业务逻辑涉及读取 MySQL 数据库(目前是在容器启动期间创建的数据源 bean),对于 MySQL 数据库中 SQL_SERVER_MAPPING 表中的每个条目,我需要连接到该数据库并运行报告。

我正在考虑为每个 SQL 服务器实例做一些事情

public DataSource getdataSource(String url, String u, String p, String class) 
    return DataSourceBuilder
        .create()
        .username(u)
        .password(p)
        .url(url)
        .driverClassName(class)
        .build();


public JdbcTemplate jdbcTemplate(DataSource datasource)  
        return new JdbcTemplate(dataSource); 
     

这是一个为给定 url 生成数据源并从中创建必要的 jdbcTemplate 的构建器。所以基本上为每个 SQL 服务器配置创建一个。 我担心我将创建大约 5000 个数据源和 5000 个 jdbcTemplate 甚至更多。这对我来说听起来不对。在这里的正确出行方式是什么?

有没有办法在我完成后立即删除数据源对象或回收它们?

我是否应该在我的 Spring 应用程序中缓存这些数据源对象,这样我就不必每次都创建一个并丢弃它。但这意味着,我需要缓存 5000 个(或者将来可能更多)。

Spring docs 说

DataSource 应始终配置为 Spring IoC 容器中的 bean。在第一种情况下,bean 直接提供给服务;在第二种情况下,它被提供给准备好的模板。

所以这让我更难了。

谢谢

【问题讨论】:

【参考方案1】:

您可以定义一个具有作用域原型的 bean myBean 并使用 BeanFactory 的 getBean(String name, Object... args) 方法。 args 将是发送给构造函数的 args(在您的情况下,这些将是数据库连接)。该 bean 将返回一个 jdbcTemplate,该 jdbcTemplate 由连接属性定义的数据源构成。这个模板可以在其他类中进一步使用。

由于 bean 的作用域是原型,所以创建的实例将在当前对象被使用后被垃圾回收。如果您有内存限制,这会有所帮助,在创建对象方面真正繁重的工作是在获取实际的数据库连接时完成的。在重用连接的情况下,缓存将是一个很好的解决方案。

在此处查看此 bean 和方法用法的示例:spring bean with dynamic constructor value

【讨论】:

以上是关于我怎样才能在春天拥有一个不是 bean 的数据源对象?的主要内容,如果未能解决你的问题,请参考以下文章

我怎样才能拥有一个遵守开闭原则的行为丰富的域实体?

我怎样才能拥有一个完全透明的 UIAlertView?

我怎样才能拥有一个同时包含图像和文本的 UIBarButtonItem?

我怎样才能拥有一个只为默认的、未更改的控件可视树创建容器的 ControlTemplate?

我怎样才能增加分数?

使用 SBT,我怎样才能拥有两个具有不同设置的不同 proguard 任务?