MongoDB Lifecycle 事件访问 MongoTemplate

Posted

技术标签:

【中文标题】MongoDB Lifecycle 事件访问 MongoTemplate【英文标题】:MongoDB Lifecycle event access to MongoTemplate 【发布时间】:2012-08-22 02:47:12 【问题描述】:

我正在尝试使用 Spring Data Mongodb 为我的 mongodb 文档实现版本控制系统。我想我会利用 Mongo 生命周期事件

Mongo Lifecycle Events in Spring

我想做的是听onBeforeSave 并获取文档的原始版本,并获取两者之间的差异。

@Override
public void onBeforeSave(Table table, DBObject dbo) 

    if (table.getId() != null) 
        TableChange change = new TableChange();

        Table beforeTable = mongoOperations.findById(table.getId(), Table.class);

        if (!beforeTable.getName().equals(table.getName())) 
            change.setName(table.getName());
        

        MapDifference<String, Column> diff = Maps.difference(beforeTable.getColumns(), table.getColumns());

        logger.debug(diff.entriesInCommon().toString());
        logger.debug(diff.entriesDiffering().toString());
        logger.debug(diff.entriesOnlyOnLeft().toString());
        logger.debug(diff.entriesOnlyOnRight().toString());         

        table.addChange(change);
    

我遇到的问题是我无法获得对 mongoOperations 的引用。它不断创建循环引用。我是否@Autowire:

Autowire 注入

Mongo 配置:

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
    <constructor-arg name="mongoConverter" ref="fooConverter" />
    <property name="writeResultChecking" value="EXCEPTION" />
</bean>

<bean class="com.example.listener.document.TableListener"></bean>

听众:

public class TableListener extends AbstractMongoEventListener<Table> 

    private static final Logger logger = LoggerFactory.getLogger(TableListener.class);

    @Autowired MongoTemplate mongoTemplate;

    @Override
    public void onBeforeSave(Table table, DBObject dbo) 
        // .... 
    

或使用Setter Injection

Setter 注入

Mongo 配置:

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
    <constructor-arg name="mongoConverter" ref="fooConverter" />
    <property name="writeResultChecking" value="EXCEPTION" />
</bean>

<bean class="com.example.listener.document.TableListener">
    <property name="mongoTemplate" ref="mongoTemplate" />
</bean>

听众:

public class TableListener extends AbstractMongoEventListener<Table> 

    private static final Logger logger = LoggerFactory.getLogger(TableListener.class);

    private MongoTemplate mongoTemplate;

    public void setMongoTemplate(MongoTemplate mongoTemplate) 
        this.mongoTemplate = mongoTemplate;
    

    @Override
    public void onBeforeSave(Table table, DBObject dbo) 
        // .... 
    

在生命周期事件中处理文档版本控制对我来说很有意义。我用 php/Doctrine/Mongo 做了类似的事情

How I did it with Doctrine/PHP

在 Doctrine 的情况下,我在生命周期回调中获得了对文档管理器的引用。有什么线索可以用 Spring Data 做同样的事情吗?

【问题讨论】:

您的侦听器类是 Spring 托管的 bean 吗?我使用 MongoTemplate @Autowired 参考进行了尝试,它对我有用 是的,我相信是的。我做了一些编辑,包括我是如何尝试自动接线的。这看起来像你是怎么做的吗? 把你的 MappingMongoConverter 的样子也放在这里 - 似乎你已经定制了它 - 也许问题就在那里。在1.2.0版本的AbstractMongoEventListener中给MongoTemplate添加autowired注入是没有问题的。 @eric 你解决过这个问题吗? 你有没有尝试实现ApplicationContextAware? 【参考方案1】:

我试过了,很少有基于 java 的配置

    带显式参数:

    @Configuration
    public static class ListenerConfiguration 
    
       @Bean
       public TableListener tableListener(MongoOperations mongoOperations) 
           return new TableListener(mongoOperations);
       
    
    
    

    使用@Autowired

    @Configuration
    public static class ListenerConfiguration 
    
        @Bean
        public TableListener tableListener() 
            return new TableListener();
        
    
    
    

所有这些都完美无缺。

    一个选项是 - 你只是忘记添加

    <context:annotation-config/>
    

    在您的 xml 配置中,尽管这不能解释 setter 注入失败。

    您可能在某处覆盖了 bean 名称

还有更多。

不管怎样,问题在于你如何使用Spring,而不是你提供的spring配置,没关系。

【讨论】:

以上是关于MongoDB Lifecycle 事件访问 MongoTemplate的主要内容,如果未能解决你的问题,请参考以下文章

Python访问MongoDB,并且转换成Dataframe

[Mo]MongoDB分片副本集搭建

Lifecycle详细分析

安卓学习01

聊聊MongoDB赎金事件

无法访问“FavoriteBottomDialogFragment”的超类型“androidx.lifecycle.HasDefaultViewModelProviderFactory”。检查你的模块