@Document注释中的MongoDB和SpEL表达式

时间:2013-08-08 14:55:25

标签: java spring spring-data spring-data-mongodb spring-el

我正在尝试使用SpEL根据我定义的一些规则将相同的Document加载到不同的集合中。

所以从我拥有的东西开始:

- 首先是文件:

@Document(collection = "#{@mySpecialProvider.getTargetCollectionName()}")
public class MongoDocument {
// some random fields go in
}

-second我有应该提供集合名称的提供者bean:

@Component("mySpecialProvider")
public class MySpecialProvider {

public String getTargetCollectionName() {
// Thread local magic goes in bellow
    String targetCollectionName = (String) RequestLocalContext.getFromLocalContext("targetCollectionName");
    if (targetCollectionName == null) {
        targetCollectionName = "defaultCollection";
    }
    return targetCollectionName;
 }
}

问题在于,当我尝试将文档插入应由提供者生成的特定集合时,我得到以下stacktrace:

org.springframework.expression.spel.SpelEvaluationException:EL1057E:(pos 1):在上下文中没有注册bean解析器以解析对bean'mySpecialProvider'的访问

我也尝试过使用spring组件 ApplicationContextAware ,但仍然没有运气。

2 个答案:

答案 0 :(得分:3)

正如我所承诺的那样,我回答了我的问题。 要使其正常工作,您需要在应用程序上下文XML文件中对 mongoTemplate bean进行以下设置:

<mongo:db-factory dbname="${myDatabaseName.from.properties.file}" mongo-ref="mongo"/>
<bean id="mongoMappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext"/>   
<bean id="mappingMongoConverter" class="org.springframework.data.mongodb.core.convert.MappingMongoConverter" c:mongoDbFactory-ref="mongoDbFactory"
            c:mappingContext-ref="mongoMappingContext"/>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"
            c:mongoDbFactory-ref="mongoDbFactory" c:mongoConverter-ref="mappingMongoConverter"/>

使用上面的设置和我在我的问题中建议的解决方案。您可以使用相同的域对象,并根据您选择的设置将其存储到多个集合中。

修改

由于有人在相关问题中提出要求,我还会在此更新ThreadLocal上下文的逻辑:

创建一个包含以下实现的 RequestLocalContext 类:

private static final ThreadLocal<Map> CONTEXT = new ThreadLocal<Map>() {
        protected Map initialValue() {
            Map localMap = new HashMap();
            localMap.put(LocalContextKeys.CONVERSATION_CONTEXT, new HashMap());
            return localMap;
        };
    };

public static void putInLocalContext(Object key, Object value) {
    Map localMap = CONTEXT.get();
    localMap.put(key, value);
}

 public static Object getFromLocalContext(Object key) {
    Map localMap = CONTEXT.get();
    return localMap.get(key);
}

其中 LocalContextKeys 是包含 ThreadLocal 上下文地图中允许的键的枚举。请注意,这些键是用户定义的,因此您可以根据需要随意添加。

答案 1 :(得分:1)

您可以使用mongo模板的方法:save(Object objectToSave,String collectionName)。