![](/img/trans.png)
[英]Expose @Service methods as Rest endpoints using spring-data-rest
[英]Why does Spring Data MongoDB not expose events for update…(…) methods?
似乎mongoOperations的更新不会触发AbstractMongoEventListener 中的事件。
目前有没有办法监听如下更新事件? 如果是这样的话,这似乎是一个很大的遗漏。
MongoTemplate.updateMulti()
谢谢!
这不是疏忽。 事件至少围绕域对象或文档的生命周期设计,这意味着它们通常包含您感兴趣的域对象的实例。
另一方面,更新完全在数据库中处理。 所以在MongoTemplate
中没有处理文档甚至域对象。 考虑这基本上与 JPA @EntityListener
s 仅针对首先加载到持久性上下文中的实体触发的方式相同,但不会在执行查询时触发,因为在数据库中执行查询。
我知道现在回答这个问题为时已晚,我对MongoTemplate.findAndModify
方法有同样的情况,我需要事件的原因是为了审计目的。 这是我所做的。
1.EventPublisher(这是MongoTemplate的方法)
public class CustomMongoTemplate extends MongoTemplate {
private ApplicationEventPublisher applicationEventPublisher;
@Autowired
public void setApplicationEventPublisher(ApplicationEventPublisher
applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
//Default Constructor here
@Override
public <T> T findAndModify(Query query, Update update, Class<T> entityClass) {
T result = super.findAndModify(query, update, entityClass);
//Publishing Custom Event on findAndModify
if(result!=null && result instanceof Parent)//All of my Domain class extends Parent
this.applicationEventPublisher.publishEvent(new AfterFindAndModify
(this,((Parent)result).getId(),
result.getClass().toString())
);
return result;
} }
2.应用事件
public class AfterFindAndModify extends ApplicationEvent {
private DocumentAuditLog documentAuditLog;
public AfterFindAndModify(Object source, String documentId,
String documentObject) {
super(source);
this.documentAuditLog = new DocumentAuditLog(documentId,
documentObject,new Date(),"UPDATE");
}
public DocumentAuditLog getDocumentAuditLog() {
return documentAuditLog;
}
}
3.应用监听器
public class FindandUpdateMongoEventListner implements ApplicationListener<AfterFindAndModify> {
@Autowired
MongoOperations mongoOperations;
@Override
public void onApplicationEvent(AfterFindAndModify event) {
mongoOperations.save(event.getDocumentAuditLog());
}
}
进而
@Configuration
@EnableMongoRepositories(basePackages = "my.pkg")
@ComponentScan(basePackages = {"my.pkg"})
public class MongoConfig extends AbstractMongoConfiguration {
//.....
@Bean
public FindandUpdateMongoEventListner findandUpdateMongoEventListner(){
return new FindandUpdateMongoEventListner();
}
}
您可以监听数据库更改,甚至是完全在程序之外的更改(MongoDB 4.2 和更新版本)。
(代码使用kotlin语言。Java相同)
@Autowired private lateinit var op: MongoTemplate
@PostConstruct
fun listenOnExternalChanges() {
Thread {
op.getCollection("Item").watch().onEach {
if(it.updateDescription.updatedFields.containsKey("name")) {
println("name changed on a document: ${it.updateDescription.updatedFields["name"]}")
}
}
}.start()
}
此代码仅在启用复制时有效。 即使只有一个节点,您也可以启用它:
将以下副本集详细信息添加到 mongodb.conf(/etc/mongodb.conf 或 /usr/local/etc/mongod.conf 或 C:\\Program Files\\MongoDB\\Server\\4.0\\bin\\mongod.cfg)文件
replication:
replSetName: "local"
重启 mongo 服务,然后打开 mongo 控制台并运行以下命令:
rs.initiate()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.