Spring boot @RepositoryEventHandler事件以@RepositoryRestController停止

Spring boot @RepositoryEventHandler事件以@RepositoryRestController停止,spring-boot,java-8,spring-data,spring-data-rest,Spring Boot,Java 8,Spring Data,Spring Data Rest,当我为一个实体创建一个@RepositoryRestController时,关联的@RepositoryEventHandler方法不会在Spring Data REST中通过Spring Boot 1.4.0.M3(也是Spring Boot 1.3.5)触发——这是一个bug还是按设计的 我有一个带有@RepositoryEventHandler的账户实体: @Slf4j @Component @RepositoryEventHandler(Account.class) public cla

当我为一个实体创建一个
@RepositoryRestController
时,关联的
@RepositoryEventHandler
方法不会在Spring Data REST中通过Spring Boot 1.4.0.M3(也是Spring Boot 1.3.5)触发——这是一个bug还是按设计的

我有一个带有
@RepositoryEventHandler
账户
实体:

@Slf4j
@Component
@RepositoryEventHandler(Account.class)
public class AccountEventBridge {

    @HandleBeforeCreate
    public void handleBeforeCreate(Account account){
        log.info("Before create " + account);
    }

    @HandleAfterCreate
    public void handleAfterCreate(Account account){
        log.info("Created " + account);
    }
}
@RepositoryRestController
public class AccountRespositoryRestController {

    private final AccountRepository repository;

    @Autowired
    public AccountRespositoryRestController(AccountRepository repository) {
        this.repository = repository;
    }

    @RequestMapping(method = RequestMethod.POST,value = "/accounts")
    public @ResponseBody PersistentEntityResource post(
        @RequestBody Account account,
        PersistentEntityResourceAssembler assembler) {

        // ...
        Account entity = this.repository.save(account);
        return assembler.toResource(entity);
    }
}
当我发布以下内容时,他们应该触发哪一项:

curl -H "Content-Type: application/json" -X POST 
  -d '{"name":"aaa", "owner":{"email":"aaa@1010","password":"snap"}}'
  http://localhost:8080/api/accounts
除非我添加
@RepositoryRestController

@Slf4j
@Component
@RepositoryEventHandler(Account.class)
public class AccountEventBridge {

    @HandleBeforeCreate
    public void handleBeforeCreate(Account account){
        log.info("Before create " + account);
    }

    @HandleAfterCreate
    public void handleAfterCreate(Account account){
        log.info("Created " + account);
    }
}
@RepositoryRestController
public class AccountRespositoryRestController {

    private final AccountRepository repository;

    @Autowired
    public AccountRespositoryRestController(AccountRepository repository) {
        this.repository = repository;
    }

    @RequestMapping(method = RequestMethod.POST,value = "/accounts")
    public @ResponseBody PersistentEntityResource post(
        @RequestBody Account account,
        PersistentEntityResourceAssembler assembler) {

        // ...
        Account entity = this.repository.save(account);
        return assembler.toResource(entity);
    }
}
当我注释掉
@RepositoryRestController
注释时,
@RepositoryEventHandler
方法再次触发

看起来它们应该独立运行,因为它们在SpringDataREST中运行两个不同的概念层——或者我误解了什么

如果这是故意的,那就很不幸了——我必须实现所有HTTP方法来为任何具有
@RepositoryRestController
的实体创建事件。这真的是目的吗?

已经实现了。:-)

@RepositoryRestController
实现中定义的方法将替换发布
@RepositoryEventHandler
事件的默认方法

但是添加这些事件很容易,使
@RepositoryRestControll
成为
ApplicationEventPublisherAware
实现,并像默认的
RepositoryEntityController
实现那样发布事件:

@Slf4j
@RepositoryRestController
@AllArgConstructor
public class AccountRespositoryRestController 
    implements ApplicationEventPublisherAware {

    private final AccountRepository repository;
    private ApplicationEventPublisher publisher;

    @Override
    public void setApplicationEventPublisher(
        ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    @RequestMapping(method = RequestMethod.POST,value = "/accounts")
    public @ResponseBody PersistentEntityResource post(
        @RequestBody Account account,
        PersistentEntityResourceAssembler assembler) {

        // ...
        publisher.publishEvent(new BeforeCreateEvent(account));
        Account entity = this.repository.save(account);
        publisher.publishEvent(new AfterCreateEvent(entity));

        return assembler.toResource(entity);
    }
}
您还可以插入发布服务器,而无需使类
ApplicationEventPublisherAware

@Slf4j
@RepositoryRestController
@AllArgConstructor
public class AccountRespositoryRestController {

    private final AccountRepository repository;
    private final ApplicationEventPublisher publisher;

    @RequestMapping(method = RequestMethod.POST,value = "/accounts")
    public @ResponseBody PersistentEntityResource post(
        @RequestBody Account account,
        PersistentEntityResourceAssembler assembler) {

        // ...
        publisher.publishEvent(new BeforeCreateEvent(account));
        Account entity = this.repository.save(account);
        publisher.publishEvent(new AfterCreateEvent(entity));

        return assembler.toResource(entity);
    }
}

“因为它们操作两个不同的层”,而不是根据“REST导出器发出的事件”。REST导出器,而不是数据库。这是Spring数据REST的一个功能,而不是Spring数据。是的,@zeroflagL、
@RepositoryEventHandler
@RepositoryRestController
都是Spring数据REST模块的一部分;上面我提到的是SDR中的两个不同的层次,而我认为这两个不同的概念层,@ ZoFrAGLL,显然SDR与您的解释一致。有关详细信息,请参见下面的解决方案。