非Spring项目中如何向Hazelcast MapStore注入已创建对象
在非Spring的Vert.x项目中向Hazelcast MapStore注入已构造的对象
我需要把已创建好的对象注入到Hazelcast MapStore中。Hazelcast官方文档里的示例是通过XML配置传递属性,然后在MapStore的init方法里用这些属性新建对象。但在Vert.x环境下,怎么传递已经构造好的连接对象呢?这是非Spring项目,没法用@SpringAware和Bean注入。
原文档中的XML配置示例:
<hazelcast> ... <map name="supplements"> <map-store enabled="true" initial-mode="LAZY"> <class-name>com.hazelcast.loader.YourMapStoreImplementation</class-name> <properties> <property name="mongo.url">mongodb://localhost:27017</property> <property name="mongo.db">mydb</property> <property name="mongo.collection">supplements</property> </properties> </map-store> </map> ... </hazelcast>
在配置中指定数据库属性后,您需要实现MapLoaderLifecycleSupport接口,并在init()方法中使用这些属性,如下所示:
原文档中的MapStore实现示例:
public class YourMapStoreImplementation implements MapStore<String, Supplement>, MapLoaderLifecycleSupport { private MongoClient mongoClient; private MongoCollection collection; public YourMapStoreImplementation() { } @Override public void init(HazelcastInstance hazelcastInstance, Properties properties, String mapName) { String mongoUrl = (String) properties.get("mongo.url"); String dbName = (String) properties.get("mongo.db"); String collectionName = (String) properties.get("mongo.collection"); this.mongoClient = new MongoClient(new MongoClientURI(mongoUrl)); this.collection = mongoClient.getDatabase(dbName).getCollection(collectionName); } }
可行解决方案
方法1:通过Hazelcast用户上下文传递对象
利用Hazelcast实例的用户上下文存储已构造的对象,在MapStore的init方法中取出使用:
- 初始化Hazelcast时存入对象:
Vertx vertx = Vertx.vertx(); // 假设已构造好MongoClient连接 MongoClient existingMongoClient = ...; Config hazelcastConfig = new Config(); // 配置MapStore,仅指定类名即可 MapConfig mapConfig = hazelcastConfig.getMapConfig("supplements"); MapStoreConfig mapStoreConfig = new MapStoreConfig(); mapStoreConfig.setEnabled(true) .setInitialMode(MapStoreConfig.InitialMode.LAZY) .setClassName("com.hazelcast.loader.YourMapStoreImplementation"); mapConfig.setMapStoreConfig(mapStoreConfig); // 将已创建的对象放入Hazelcast用户上下文 hazelcastConfig.getUserContext().put("existingMongoClient", existingMongoClient); HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance(hazelcastConfig);
- 修改MapStore的
init方法获取对象:
public class YourMapStoreImplementation implements MapStore<String, Supplement>, MapLoaderLifecycleSupport { private MongoClient mongoClient; private MongoCollection collection; public YourMapStoreImplementation() { } @Override public void init(HazelcastInstance hazelcastInstance, Properties properties, String mapName) { // 从用户上下文取出已构造的MongoClient this.mongoClient = (MongoClient) hazelcastInstance.getUserContext().get("existingMongoClient"); this.collection = mongoClient.getDatabase("mydb").getCollection("supplements"); // 数据库名、集合名也可存入用户上下文,按需取出 } // 实现MapStore其他方法... }
方法2:手动实例化MapStore并传入对象
跳过配置类名的方式,直接将已初始化的MapStore实例传入Hazelcast配置:
- 修改MapStore添加带参构造器:
public class YourMapStoreImplementation implements MapStore<String, Supplement> { private MongoClient mongoClient; private MongoCollection collection; // 接收已构造的MongoClient的构造器 public YourMapStoreImplementation(MongoClient mongoClient) { this.mongoClient = mongoClient; this.collection = mongoClient.getDatabase("mydb").getCollection("supplements"); } // 实现MapStore其他方法... }
- 在Vertx中手动配置:
Vertx vertx = Vertx.vertx(); MongoClient existingMongoClient = ...; // 手动创建MapStore实例,传入已有的连接对象 YourMapStoreImplementation mapStore = new YourMapStoreImplementation(existingMongoClient); Config hazelcastConfig = new Config(); MapConfig mapConfig = hazelcastConfig.getMapConfig("supplements"); MapStoreConfig mapStoreConfig = new MapStoreConfig(); mapStoreConfig.setEnabled(true) .setInitialMode(MapStoreConfig.InitialMode.LAZY) .setImplementation(mapStore); // 直接传入实例而非类名 mapConfig.setMapStoreConfig(mapStoreConfig); HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance(hazelcastConfig);
注意事项
- 方法2需保证MapStore实例是线程安全的,Hazelcast会在多线程环境中调用它。
- 集群部署场景下,方法1需确保每个节点初始化时都存入自己的连接对象(用户上下文为节点本地存储)。
内容的提问来源于stack exchange,提问作者Sergey Afinogenov
相关产品推荐
相关产品推荐

