我知道已经很晚了,但是今天我刚刚遇到了这个问题,我想也许最好在这里分享一下。
由于 MongoTemplate(及其默认转换器)是在我们的自定义转换器之后初始化的,因此无法将它们直接注入到我们的转换器中,但我们可以通过在转换器中实现 ApplicationContextAware 来访问它们。
访问mongoTemplate后,我们可以分别调用mongoTemplate.getConverter().read和mongoTemplate.getConverter().write方法将读写转换委托给它。
让我们看一个例子。假设我们有两个 POJO:
public class Outer {
public String var1;
public int var2;
public Inner inner;
}
public class Inner {
public String var3;
public String var4;
}
WriteConverter 可能是这样的:
import org.bson.Document;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;
@Component
public class CustomWriteConverter implements Converter<Outer, Document>, ApplicationContextAware {
private ApplicationContext applicationContext;
private MongoTemplate mongoTemplate;
@Override
public Document convert(Outer source) {
// initialize the mongoTemplate
if (mongoTemplate == null) {
this. mongoTemplate = applicationContext.getBean(MongoTemplate.class);
}
// do some custom stuff
Document document = new Document();
document.put("var1", source.var1);
document.put("var2", source.var2);
// Using MongoTemplate's converters
Document inner = new Document();
mongoTemplate.getConverter().write(source.inner, inner);
document.put("inner", inner);
return document;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
还有 ReadConverter:
import org.bson.Document;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;
@Component
public class CustomReadConverter implements Converter<Document, Outer>, ApplicationContextAware {
private ApplicationContext applicationContext;
private MongoTemplate mongoTemplate;
@Override
public Outer convert(Document source) {
// initialize the mongoTemplate
if (mongoTemplate == null) {
this. mongoTemplate = applicationContext.getBean(MongoTemplate.class);
}
// do some custom stuff
Outer outer = new Outer();
outer.var1 = source.getString("var1");
outer.var2 = source.getInteger("var2");
// Using MongoTemplate's converters
Inner inner = mongoTemplate.getConverter().read(Inner.class, (Document) source.get("inner"));
outer.inner = inner;
return outer;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
mongoTemplate 可以被多个线程初始化(因为它处于竞争状态),但是由于它的作用域是单例,所以没有问题。
现在唯一要做的就是注册我们的转换器。