У меня есть сервис, который предоставляет доступ к клиенту MongoDB:
// MongoService.java
public interface MongoService {
public MongoClient getClient();
}
И его реализация:
// MongoServiceImpl.java
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class MongoServiceImpl implements MongoService {
MongoClient client = null;
@PostConstruct
public void init() {
client = new MongoClient();
}
@Override
@Lock(LockType.READ)
public MongoClient getClient() {
return client;
}
}
В целях уменьшения количества дублируемого кода, хочется сделать аннотацию, чтобы иметь возможность получать объект БД и коллекции через внедрение зависимостей:
//Mongo.java
@Target({ ElementType.FIELD, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Mongo {
@Nonbinding String database() default "default";
@Nonbinding String collection() default "";
}
И соответствующий Producer:
// MongoProducer.java
@Stateless
public class MongoProducer {
@EJB
MongoService mongoService;
@Produces
@Mongo
public MongoDatabase getDatabase(InjectionPoint injectionPoint) {
Mongo annotation = injectionPoint.getAnnotated().getAnnotation(Mongo.class);
return mongoService.getClient().getDatabase(annotation.database());
}
@Produces
@Mongo
public MongoCollection<Document> getCollection(InjectionPoint injectionPoint) {
Mongo annotation = injectionPoint.getAnnotated().getAnnotation(Mongo.class);
String collectionName = annotation.collection();
if (Objects.equals(collectionName, "")) {
return null;
}
return mongoService.getClient().getDatabase(annotation.database()).getCollection(collectionName);
}
}
В версии драйвера >3.0 коллекции параметризуются типом документа. По-умолчанию, это
org.bson.Document
, но нужно иметь возможность использовать свой тип.
Что нужно добавить в аннотацию
@Mongo
и класс
MongoProducer
, чтобы можно было использовать свой тип документа вот так:
@Stateless
public class FooBean {
@Inject
@Mongo(collection = "foo", documentType = MyDocument.class)
MongoCollection<MyDocument> collection;
...
}