@RepositoryEventHandler事件使用@RepositoryRestController停止

时间:2016-06-02 22:35:12

标签: spring-boot java-8 spring-data spring-data-rest

当我为实体创建@RepositoryRestController时,Spring Spring 1.4.0.M3(也是Spring Boot 1.3.5)不会在Spring Data REST中触发相关的@RepositoryEventHandler方法 - 是这是一个错误,或按设计

我有一个Account实体@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);
    }
}

在我发布POST时触发它们:

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

除非我添加@RepositoryRestController

@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方法会再次触发。

看起来这些应该独立运行,因为它们在Spring Data REST中运行两个不同的概念层 - 或者我误解了什么?

如果这是故意的,那很不幸 - 我必须实现所有HTTP方法,以便为@RepositoryRestController的任何实体自己创建事件。这真的是意图吗?

1 个答案:

答案 0 :(得分:7)

已实施。 : - )

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

但是,添加这些事件很容易,@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);
    }
}