调用Hazelcast Sources.jdbc时如何正确使用Spring注册的DataSource Bean
Hazelcast Jet JDBC Source依赖Spring DataSource注入失效问题解决方案
问题根源
你遇到的核心问题在于:Sources.jdbc的newConnectionFn参数会被序列化后分发到Jet集群所有节点执行。自定义的DataSourceBeanHolder作为实现SupplierEx的序列化对象,反序列化时仅会重建对象实例,Hazelcast不会自动触发Spring的依赖注入逻辑——包括@Autowired字段赋值、setApplicationContext方法调用。哪怕配置了SpringManagedContext,它也不会主动处理这类函数型作业参数的注入流程。
解决方案
不要通过自定义序列化对象持有Spring Bean,改用JetSpringServiceFactories.bean()在每个节点上获取本地Spring上下文里的DataSource。这个工厂类是Jet专为Spring集成设计的,会在作业执行时从节点本地的Spring上下文查找Bean,避免了序列化Bean本身的问题。
代码示例
// 创建Connection Supplier,通过Spring工厂获取本地DataSource SupplierEx<Connection> connectionSupplier = () -> { // 从当前节点的Spring上下文获取DataSource Bean DataSource dataSource = JetSpringServiceFactories.bean(DataSource.class) .create(null, null); return dataSource.getConnection(); }; // 构建JDBC Source BatchSource<YourBusinessObject> jdbcSource = Sources.jdbc( connectionSupplier, // ResultSet转业务对象的处理逻辑 resultSet -> new YourBusinessObject( resultSet.getLong("id"), resultSet.getString("content") ), // 结果集过滤条件(按需调整) rs -> true );
如果你的DataSource是通过名称注册的,可使用带Bean名称的重载方法:
JetSpringServiceFactories.bean("customDataSourceBeanName", DataSource.class)
关键说明
JetSpringServiceFactories.bean()会在每个Jet节点执行时,从本地的SpringManagedContext中查找对应Bean,保证每个节点获取到的是本地的DataSource实例,而非序列化传输的Bean对象。- 之前自定义
DataSourceBeanHolder方案失效,是因为Hazelcast对作业中的函数型参数(如SupplierEx)的序列化/反序列化流程,不会触发Spring的注入钩子,这类对象的生命周期不在Spring的管理范围内。
内容的提问来源于stack exchange,提问作者Mateusz Stefek
相关产品推荐
相关产品推荐

