MongoDB Lifecycle事件访问MongoTemplate

eri*_*ric 9 spring mongodb spring-data spring-data-mongodb

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

Spring中的Mongo生命周期事件

我想要做的是听取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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是我无法获得对mongoOperations的引用.它不断创建循环引用.是否我@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>
Run Code Online (Sandbox Code Playgroud)

监听器:

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) {
        // .... 
    }
}
Run Code Online (Sandbox Code Playgroud)

或使用Setter Injection

二传手注射

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>
Run Code Online (Sandbox Code Playgroud)

监听器:

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) {
        // .... 
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我是如何用Doctrine/PHP做的

在Doctrine的情况下,我在生命周期回调中获得对Document Manager的引用.有什么线索我怎么能用Spring Data做同样的事情?

mav*_*azy 0

我尝试过,一些基于java的配置

  1. 使用显式参数:

    @Configuration
    public static class ListenerConfiguration {
    
       @Bean
       public TableListener tableListener(MongoOperations mongoOperations) {
           return new TableListener(mongoOperations);
       }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 与@Autowired

    @Configuration
    public static class ListenerConfiguration {
    
        @Bean
        public TableListener tableListener() {
            return new TableListener();
        }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

所有这些都很完美。

  1. 一种选择是 - 您只是忘记添加

    <context:annotation-config/>
    
    Run Code Online (Sandbox Code Playgroud)

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

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

还有很多。

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